Merge pull request #7 from internetee/remove-eunit-tests

Create test suite
This commit is contained in:
Maciej Szlosarczyk 2019-07-12 16:20:19 +03:00 committed by GitHub
commit a811f187c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 1716 additions and 446 deletions

View file

@ -1,2 +1,2 @@
erlang 21.3.8 erlang 21.3.8
rebar 3.9.1 ruby 2.6.3

View file

@ -3,7 +3,15 @@ language: erlang
otp_release: otp_release:
- 21.3.8 - 21.3.8
ruby:
- 2.6.3
install:
- "rebar3 as test get-deps"
- "/bin/bash -l -c \"cd apps/epp_proxy/priv/test_backend_app && bundle install\""
script: script:
- "rebar3 eunit" - "/bin/bash -l -c \"cd apps/epp_proxy/priv/test_backend_app && bundle exec rackup --pid pidfile -D\""
- "rebar3 ct --sys_config config/test.config --readable=false --cover" - "rebar3 as test compile"
- "DEBUG=1 rebar3 ct --sys_config config/test.config --readable=false --cover --verbose=true"
- "rebar3 cover --verbose" - "rebar3 cover --verbose"

View file

@ -54,6 +54,8 @@ WORKDIR /opt/erlang/epp_proxy
COPY .tool-versions ./ COPY .tool-versions ./
RUN asdf plugin-add erlang RUN asdf plugin-add erlang
RUN asdf install RUN asdf install
RUN asdf plugin-add ruby
RUN asdf install
RUN curl https://s3.amazonaws.com/rebar3/rebar3 -o /rebar3 RUN curl https://s3.amazonaws.com/rebar3/rebar3 -o /rebar3
RUN mv /rebar3 /usr/local/bin RUN mv /rebar3 /usr/local/bin

View file

@ -82,10 +82,10 @@ of Erlang property list.
| `epp_session_url` | `https://example.com/epp/session` | EppSessionRoot | HTTP address of the session endpoints including schema and port. | `epp_session_url` | `https://example.com/epp/session` | EppSessionRoot | HTTP address of the session endpoints including schema and port.
| `epp_command_url` | `https://example.com/epp/command` | EppCommandRoot | HTTP address of the command endpoints including schema and port. | `epp_command_url` | `https://example.com/epp/command` | EppCommandRoot | HTTP address of the command endpoints including schema and port.
| `epp_error_url` | `https://example.com/epp/error` | EppErrorRoot | HTTP address of the error endpoints including schema and port. | `epp_error_url` | `https://example.com/epp/error` | EppErrorRoot | HTTP address of the error endpoints including schema and port.
| `cacertfile_path` | `/opt/ca/ca.crt.pem` | SSLCACertificateFile | Where is the client root CA located. | `cacertfile_path` | `/opt/ca/ca.crt.pem` | SSLCACertificateFile | Where is the client root CA located. Can be inside apps/epp_proxy/priv or absolute path.
| `certfile_path` | `/opt/ca/server.crt.pem` | SSLCertificateFile | Where is the server certificate located. | `certfile_path` | `/opt/ca/server.crt.pem` | SSLCertificateFile | Where is the server certificate located. Can be inside apps/epp_proxy/priv or absolute path.
| `keyfile_path` | `/opt/ca/server.key.pem` | SSLCertificateKeyFile | Where is the server key located. | `keyfile_path` | `/opt/ca/server.key.pem` | SSLCertificateKeyFile | Where is the server key located. Can be inside apps/epp_proxy/priv or absolute path.
| `crlfile_path` | `/opt/ca/crl.pem` | SSLCARevocationFile | Where is the CRL file located. | `crlfile_path` | `/opt/ca/crl.pem` | SSLCARevocationFile | Where is the CRL file located. Can be inside apps/epp_proxy/priv or absolute path.
Migrating from mod_epp Migrating from mod_epp
@ -100,6 +100,27 @@ Checklist of steps to perform if you want to migrate from mod_epp, but still use
5. If you do not feel comfortable using Erlang configuration file, you can use command line arguments and flags in format of `/epp_proxy/rel/bin/epp_proxy -epp_proxy tls_port 444`, where `-epp_proxy` is name of application, 5. If you do not feel comfortable using Erlang configuration file, you can use command line arguments and flags in format of `/epp_proxy/rel/bin/epp_proxy -epp_proxy tls_port 444`, where `-epp_proxy` is name of application,
followed by configuration parameter name and value. followed by configuration parameter name and value.
Testing
----
The application comes with test suite written with common_test. For integration
tests, there is a small Roda application located in `apps/epp_proxy/priv/test_backend_app`.
It has been written with Ruby 2.6.3.
There is also a number of generated ssl certificates that are used only for testing. Those are
valid until 2029 and they are located in `apps/epp_proxy/priv/test_ca`.
You need to start the backend application before running the test suite. To start it as a deamon,
from the root folder of the project, execute:
```bash
$ /bin/bash -l -c "cd apps/epp_proxy/priv/test_backend_app && bundle install"
$ /bin/bash -l -c "cd apps/epp_proxy/priv/test_backend_app && bundle exec rackup --pid pidfile -D"
```
After you finish testing, you can stop the process by reading the stored pid:
$ kill `cat apps/epp_proxy/priv/test_backend_app/pidfile`
TODO TODO
---- ----

View file

@ -0,0 +1,8 @@
# frozen_string_literal: true
source "https://rubygems.org"
gem "puma"
gem "roda"
gem "rack-unreloader"
gem "tilt"

View file

@ -0,0 +1,23 @@
GEM
remote: https://rubygems.org/
specs:
nio4r (2.4.0)
puma (4.0.0)
nio4r (~> 2.0)
rack (2.0.7)
rack-unreloader (1.7.0)
roda (3.21.0)
rack
tilt (2.0.9)
PLATFORMS
ruby
DEPENDENCIES
puma
rack-unreloader
roda
tilt
BUNDLED WITH
1.17.2

View file

@ -0,0 +1,8 @@
# frozen_string_literal: true
require "rack/unreloader"
Unreloader = Rack::Unreloader.new() { EppServer }
Unreloader.require("epp_server.rb") { "EppServer" }
run(Unreloader)

View file

@ -0,0 +1,37 @@
require 'roda'
class EppServer < Roda
plugin :render
route do |r|
response['Content-Type'] = 'application/xml'
r.on "session" do
r.get "hello" do
render("session/hello")
end
r.post "login" do
render("session/login")
end
r.post "logout" do
render("session/logout")
end
end
r.on "command" do
r.post "poll" do
render("command/poll")
end
end
r.get "error" do
@code = r.params['code']
@msg = r.params['msg']
render("error")
end
end
end

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="lib/schemas/epp-ee-1.0.xsd">
<response>
<result code="1300">
<msg>Command completed successfully; no messages</msg>
</result>
<trID>
<clTRID>foo bar baz</clTRID>
<svTRID>ccReg-8688842425</svTRID>
</trID>
</response>
</epp>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="lib/schemas/epp-ee-1.0.xsd">
<response>
<result code="<%= @code %>">
<msg lang="en">
<%= @msg %>
</msg>
</result>
<trID>
<svTRID>ccReg-4018856528</svTRID>
</trID>
</response>
</epp>

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="lib/schemas/epp-ee-1.0.xsd">
<greeting>
<svID>EPP server (EIS)</svID>
<svDate>2019-07-11T09:35:29Z</svDate>
<svcMenu>
<version>1.0</version>
<lang>en</lang>
<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>
<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:keyrelay-1.0</objURI>
<svcExtension>
<extURI>urn:ietf:params:xml:ns:secDNS-1.1</extURI>
<extURI>https://epp.tld.ee/schema/eis-1.0.xsd</extURI>
</svcExtension>
</svcMenu>
<dcp>
<access>
<all/>
</access>
<statement>
<purpose>
<admin/>
<prov/>
</purpose>
<recipient>
<public/>
</recipient>
<retention>
<stated/>
</retention>
</statement>
</dcp>
</greeting>
</epp>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="lib/schemas/epp-ee-1.0.xsd">
<response>
<result code="1000">
<msg>Command completed successfully</msg>
</result>
<trID>
<svTRID>ccReg-5886259930</svTRID>
</trID>
</response>
</epp>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="lib/schemas/epp-ee-1.0.xsd">
<response>
<result code="1500">
<msg>Command completed successfully; ending session</msg>
</result>
<trID>
<svTRID>ccReg-3475281342</svTRID>
</trID>
</response>
</epp>

View file

@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFPTCCAyWgAwIBAgIJAIcovwhumxzlMA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD
VQQGEwJFRTERMA8GA1UECAwISGFyanVtYWExEDAOBgNVBAcMB1RhbGxpbm4xIzAh
BgNVBAoMGkVlc3RpIEludGVybmV0aSBTaWh0YXN1dHVzMRowGAYDVQQDDBFlcHBf
cHJveHkgdGVzdCBjYTEgMB4GCSqGSIb3DQEJARYRaGVsbG9AaW50ZXJuZXQuZWUw
HhcNMTkwNzExMTM0MTQyWhcNMjkwNzA4MTM0MTQyWjCBkjELMAkGA1UEBhMCRUUx
ETAPBgNVBAgMCEhhcmp1bWFhMRAwDgYDVQQHDAdUYWxsaW5uMRkwFwYDVQQKDBBF
ZXN0aUludGVybmV0aVNBMRAwDgYDVQQLDAdBcmVuZHVzMSAwHgYJKoZIhvcNAQkB
FhFoZWxsb0BpbnRlcm5ldC5lZTEPMA0GA1UEAwwGKi50ZXN0MIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqoZLIpFR96bIwxk9GvzTeTnsPMpTJ/fI+SWX
Qh5UflAIG74Hl+aBW+k8jIZ+VxwXwn7uwY7fdtemu9CzCqYK4pqZg168IEC00Vne
C7gifaMWgBd/DNiv3FafNpTihdMZrZi8xLJIuNw8XLaDebGQrrfOWw1Cewum/MJa
IFnIBttsBq+jFwKtAJ9RgNg6Ul2xOGpqtrLmU21HmIzm9hqbeaWINIX1QDVC2ZWd
gVXgoEID/RLUc8A+riVUdaKzG9kCrtuzGO8PhXoF5BJWtsrAcYFQev3jVRKplSFh
whijh2MY14qA21wseNMF7+fSCjhuvEomxpzNQSH0UADHW0p17wIDAQABo4GQMIGN
MB8GA1UdIwQYMBaAFP135kpzvaU8ZbO5z7UVlVkIZGgQMAkGA1UdEwQCMAAwCwYD
VR0PBAQDAgTwMFIGA1UdEQRLMEmCBHRlc3SCDXJlZ2lzdHJ5LnRlc3SCDGF1Y3Rp
b24udGVzdIIPcmVzdC13aG9pcy50ZXN0gghlcHAudGVzdIIJcmVwcC50ZXN0MA0G
CSqGSIb3DQEBCwUAA4ICAQBvi2Uy0iYuMWyS8hdZOvp3jdTqq/HI0JfFlT5YUwv0
ezkjyBLw4A9+dMvy8HELyzhUeHd09nmB+/TJ9RWQBCgIcHilQ5nFXd0h5hNX+rtC
kdDd8x9QRBHN82EFIwXQ6/FXLz92DZ4Z5ZQOEGM5AFi02GwFI9fhvZg2vGL3aD5Q
2V4OPulECPgVR/U6kbXQz6/Rg9DXbbMgHukLuglFIj3+dtvepp6DXYNZz6AhM64E
4/K/55yKKFKRvOzw+K+CIX3qytTvYDutDfCA593Dp2BXjMb9CVGN+nKZr9sVrDlt
qR9ya04MK/Ti0Nk8NN3ZHRASUJU3xk06/KriOj5tvVRgcqn/Jfh1JhOSULrKdx8B
4u53pRn1SCCCWiXvUAnJL3TAi6TaXKoFN6GxQZMBCl0U0wQ2XIYOCzBs74YkWqOM
1Mgq2dcX3m8GlZWzkKExc1wM+MlUmk0et8vJIgrTcIQGw0fn/TdvWy+iLNNYp0P9
YkB0rGqN0KwkAHhKt+BrRtRHkEOxQcumgvLDkwTZpAJsbrPDMOajbzwpgwSQOE1i
Z+RuZQktmZVJNJ3NPwloHZBolMnb9zDg3k3GP9+Lh1k6pDiFCf1A1QZKl52h3+kG
IDFPCaoYexOLN86ebApMWglxPPvPnfQpi9F+PWYjR02DbgSWR+/EGxygOnzjOYmS
gQ==
-----END CERTIFICATE-----

View file

@ -0,0 +1,35 @@
-----BEGIN CERTIFICATE-----
MIIGDDCCA/SgAwIBAgIJAKaLNUIy97o1MA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD
VQQGEwJFRTERMA8GA1UECAwISGFyanVtYWExEDAOBgNVBAcMB1RhbGxpbm4xIzAh
BgNVBAoMGkVlc3RpIEludGVybmV0aSBTaWh0YXN1dHVzMRowGAYDVQQDDBFlcHBf
cHJveHkgdGVzdCBjYTEgMB4GCSqGSIb3DQEJARYRaGVsbG9AaW50ZXJuZXQuZWUw
HhcNMTkwNzExMTMwMDEzWhcNMjAwNzEwMTMwMDEzWjCBlTELMAkGA1UEBhMCRUUx
ETAPBgNVBAgMCEhhcmp1bWFhMRAwDgYDVQQHDAdUYWxsaW5uMSMwIQYDVQQKDBpF
ZXN0aSBJbnRlcm5ldGkgU2lodGFzdXR1czEaMBgGA1UEAwwRZXBwX3Byb3h5IHRl
c3QgY2ExIDAeBgkqhkiG9w0BCQEWEWhlbGxvQGludGVybmV0LmVlMIICIjANBgkq
hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0PBwqZUeXZaR3mk3VTm7S78Xs4WDCfyi
RocHDU7cWhrBvFD5ZXzmbUJPPJHmljYAOLWLEyMzw0bvYVz2FSOCkBerxGFA4T17
RhjDEAmMMWiBAoFj6tNmxj3bq7nZfwaOY6KIxGiZcqx4usOQ3tQ+cxvrqzFVyX24
KScmx4l2HlmJu2boF8/C4LSYvGPys+2WKXlLr73gL+cmM7Z2Y+mNgURCKT9ODpFp
VdX9iTpmnF0UFmYq/cN8QFSNv0ErsMFDZWxAnDoy6gZzsUz3ZnznOdjB96PFV9aA
Rm5BYr7jMhu7rJPOyQNd9SfD6QhlyCSjd68p6nMFvYLG5lL5QxJSTotr3VuH1uqJ
kfFwlMPJZAj/SmFUnoIvWGCyujqx6ajVX8zBvmcalSp35LyDDCnlohorUuP9TNrI
U+k/Ap6vxfxSSIOPhq6BoFxMYASp8jo+8HdFOWce5krQh/h3vvEhu015yEXH4Vgb
6lL+nvUex35He1IQFERvRSj5IB1Yw6HpwYb7LIfjXYsfas3FuSxXz9Geb23dybYd
2MlmKeGvTyjM60BNW2ZKKQ00KgnqR62bPALbDZ/AnkzxnLd7NLVqKiSBzOOkZfaO
V7hDD78VzSklA2cSV1qaBPHUW4AgQkmDJIF/1H/K9nN/F6OWKSJ0Ug3XGwDjY3Ry
X//K+E1UNWMCAwEAAaNdMFswHQYDVR0OBBYEFP135kpzvaU8ZbO5z7UVlVkIZGgQ
MB8GA1UdIwQYMBaAFP135kpzvaU8ZbO5z7UVlVkIZGgQMAwGA1UdEwQFMAMBAf8w
CwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQDF3s887Qj2eLeJln1Z/Nem
ZR2tj0PvYEHEYKq9R8N8IM1ooZt475MgyYo7XDPcuG3MMaGY9WdjqoXlWSM7T518
U9ajFLqwNEnlfjZ33SdVDskfoRsKiDKUlvTNngn19KtAp3SBmQS6fgghlgha3tb+
W1fOgzCRwaVG4XcQfR+wijSSovFOp+5CY/FL6XUwtFCz4ZwnHgXciG91SjhEPB+J
P8iHFr4f0qV4kKv0hPfjQ7tneeho0AzI4BXOgbRJmur6+SP/gmsgBeKr1sUHuD+d
nIAlz4T2reV8FujcW3u8yT4PFIhi0mdnXKC6xKDFlmD9AQa7eUO1DHJiSZ7zAsLS
drsqMu3GhM70Uw0Oqv2aInv8N4vwF6CJ6p/wEUXTVjkjH3U/ZzuOGcl1/5sAao0r
APwRazSMcqrjc+JicpFZ6NGTwTs0G6KD0dqhhqoyoZzB/1UDR2cG5SsgSTqBUeGb
0VMW4EYU+DG1HV+OdNrFA0RgDn5o0VF3LxwAs5ErItlojFPeBDYMJvPGsMEarNHN
03JeeEK081gzLJQzFPQV1n6kE6CiGGTx4X3ptUtvvQBD/u6KNUwN5b6p5jOQBEdZ
F4PJOVZePI/dBHr98/jlcHfCOmySc+7uzPhB86OtdF/yYabImpvQ0cypZkXwzL6l
VgOJJfHQrIhSmCRVxCEJoQ==
-----END CERTIFICATE-----

View file

@ -0,0 +1 @@
8728BF086E9B1CE5

View file

@ -0,0 +1,35 @@
-----BEGIN CERTIFICATE-----
MIIGIjCCBAqgAwIBAgICEAcwDQYJKoZIhvcNAQELBQAwgZUxCzAJBgNVBAYTAkVF
MREwDwYDVQQIDAhIYXJqdW1hYTEQMA4GA1UEBwwHVGFsbGlubjEjMCEGA1UECgwa
RWVzdGkgSW50ZXJuZXRpIFNpaHRhc3V0dXMxGjAYBgNVBAMMEWVwcF9wcm94eSB0
ZXN0IGNhMSAwHgYJKoZIhvcNAQkBFhFoZWxsb0BpbnRlcm5ldC5lZTAeFw0xOTA3
MTExMzQxMDNaFw0yOTA3MDgxMzQxMDNaMIGFMQswCQYDVQQGEwJFRTERMA8GA1UE
CAwISGFyanVtYWExIzAhBgNVBAoMGkVlc3RpIEludGVybmV0aSBTaWh0YXN1dHVz
MRwwGgYDVQQDDBNsb2NhbGhvc3Qgd2ViY2xpZW50MSAwHgYJKoZIhvcNAQkBFhFo
ZWxsb0BpbnRlcm5ldC5lZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
AJ69aNDgwI4bFSDoMB6WEqL7/zcMBQnVPj3fYEBLYxpo9TEvFlkybgs2JncC5tgW
biIoE7fE/ObNt0bLnY/IKdRnMmOltnttbcAO/WmKQE2PPv/VVfGrfHi68IuVEN2b
E9YZ7GNp3cudKl4dpGW6VQkyP9Kp2Gxa3a0+2WecSNrESNXzTWre9MRI0upjIwCD
HZ9ip/4F6Lg0Z4zBa7rKXqRqR7rw8YM2LN9UvmBL6feCQdKExaJqAx0bp6ychwti
s78tOVX47pdQxL3rRPmBuXjWMjpbSAPEdL/LhAh7LpD4EJk50s1K6qq8EZPCagta
Crws2qu89MPD8MekIiM3Ygm+ouZbqySBjCHlSlVbLQ2aCpMHlSdaPWskYSJ1IXlb
lqhdgIrUehfuthR/znFZ/L6Fkqzg0MauaF7aqsrg0UAuBrZ6TOxBZLCuftPnY8qN
BUyEveKGI5Rij3JMaLuT9samBScbrOncWngFIsDrCUqpGNzkEIZQgECJtcKz1UW0
RaXOibO3KQ8PMAlwGTQFqwg6VBdH1YxmnAlunvgh/biBV6vZWLeZWpN3bx1o6FcN
30W44WQ7Hqrs58Qqq9pdlW4252iQ9XpVYP1Ps7adv9BoNX9pTxH7THUEo1y/wehh
DcQ1FnuFAMeWGU2FpBwxBasiJTBCoWQp8zMlI+4ws7V7AgMBAAGjgYkwgYYwCQYD
VR0TBAIwADALBgNVHQ8EBAMCBeAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2Vu
ZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBT7jUyzkYvC9H8s8kS7lr4jp4C9
DjAfBgNVHSMEGDAWgBT9d+ZKc72lPGWzuc+1FZVZCGRoEDANBgkqhkiG9w0BAQsF
AAOCAgEAwNXs6lvOexo/pmSzU1fqokxfxHbOSqxhH1R7x0+sfY6YufJmp2yhvb1j
Kbw/YzVhxDA4UpcwS3Cm703tb4K9Lby6DWOlaIniqEIyctldNbK8ZUPLOMCDe9mx
G4U366KtVqWt/rC7CZmDSIz8I0tXzIrMOM3xY51PY62xz8IDIILC0xkzUz30Set2
IjwWQzzfakrE+xz9rdCX//BP3kyr3+HP9Aq7DJ7mxnzlV0YmdT6kyhVTSc3Im4eG
GbtrFqLbb1AeX3tBpT/2gUuxRgYVVpY3oqVLBQMuUil1LnBH6JyO61KAgAYijwwP
gOwmp7mE9QuIpXY8Sm2+Cre4MXBqdzybJ5syyI985bp9BT0EEXuCO2cKNzUMEOub
FuNkIezW4FyApU5wdA6kn7mwELAk01hAQirh7+FQxGXAfZfTs4Bwg3F43t7KSdbO
ayjKLYg7sS+yAMsSxUMkji0fKdal6Vq1qViKSOHV/85Ou2xa9pYFpv8jypJ2igF8
LYREauAQiSMQTi5u2/pUqmPEUpC9mUjgRmoDnlHoKHM+Ma88NdpPHHdrFH4pEPVZ
ul9kwg3yLbfeO1UECtdv79j5j6yS4OUxnNErqdvoFYlQfc8DOHgB853Ym0iOBEQ/
KDNiD159/hn20mgmc5LMwY0+aPOanJpZ30AHOA9/yLpIE0/VkN0=
-----END CERTIFICATE-----

View file

@ -0,0 +1,21 @@
-----BEGIN X509 CRL-----
MIIDfTCCAWUCAQEwDQYJKoZIhvcNAQELBQAwgZUxCzAJBgNVBAYTAkVFMREwDwYD
VQQIDAhIYXJqdW1hYTEQMA4GA1UEBwwHVGFsbGlubjEjMCEGA1UECgwaRWVzdGkg
SW50ZXJuZXRpIFNpaHRhc3V0dXMxGjAYBgNVBAMMEWVwcF9wcm94eSB0ZXN0IGNh
MSAwHgYJKoZIhvcNAQkBFhFoZWxsb0BpbnRlcm5ldC5lZRcNMTkwNzExMTMxMTM0
WhcNMjkwNzA4MTMxMTM0WjBpMBMCAhACFw0xOTA1MjkwNjM5MTJaMBMCAhADFw0x
OTA1MjkwODQxMDJaMBMCAhAEFw0xOTA1MzExMTI0NTJaMBMCAhAFFw0xOTA1MzEx
MTQyMjJaMBMCAhAGFw0xOTA1MzExMjQzNDlaoDAwLjAfBgNVHSMEGDAWgBT9d+ZK
c72lPGWzuc+1FZVZCGRoEDALBgNVHRQEBAICEAgwDQYJKoZIhvcNAQELBQADggIB
ACv4opvBcQoCEkiKhVlr5bSq0vAVaTu1FloKTay0xsgDGSqQDnPR/B7ELSyoYo2A
iBuSrQREyvXOtZhlQyTHwCDnAjpgGDGdRbRJAhhbWA9/MC4oqyJLjOFxLspX2S7E
Fq4F/DbUZaW8niGGCcAUf8QnilaJLEhUT7qIJW2DpyFLd/1qLK81PBO8VW4fbKQI
z2LsrA3NijW+W192LMvHLKnE47ifW1PLM0dJimkVNrkS42ACuwnCOLfLJsIg9aRe
QsI1CY+L1F2tROedUFo6noffnm+SyMapna4SEXlQTaA1kfLtLOGVhXpBAgcewIsY
DQQCTn4oEAhZroZMPYJXYXC/pNSMUEBifXR2akO7eE5kLBgf11ZfhuEUqperviiJ
yLNzoakh3eMazIo5Qr8ZinMWP8HHZJI8GmOvJtVKAvOFmXkVm++Cnl/Ovp8skrTD
AibySMZSTgoAc+ynZYI5q6HZxJWXN/PQ/++hFyOW9aG1DTLGpV6rO+O4zNldmUIO
DTu+dUmKNamp1a6GcaY5xLSQTfV8InetxwF+gazvcmtEnqagH64EseSz4RZQLtRc
kAZLho1rPE35Ok/2eswMvQ9hOkQ7tX9dO35HYoHoVKUzdiBaPP3PCDeCC/Ei5C2n
Z1rfbtOFwF/36qyz7o+YqHaWHVc9W/koRjtrmXA1soJ2
-----END X509 CRL-----

View file

@ -0,0 +1 @@
1000

View file

@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIE3TCCAsUCAQAwgZcxCzAJBgNVBAYTAkVFMREwDwYDVQQIDAhIYXJqdW1hYTEQ
MA4GA1UEBwwHVGFsbGlubjEjMCEGA1UECgwaRWVzdGkgSW50ZXJuZXRpIFNpaHRh
c3V0dXMxHDAaBgNVBAMME2xvY2FsaG9zdCB3ZWJjbGllbnQxIDAeBgkqhkiG9w0B
CQEWEWhlbGxvQGludGVybmV0LmVlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAnr1o0ODAjhsVIOgwHpYSovv/NwwFCdU+Pd9gQEtjGmj1MS8WWTJuCzYm
dwLm2BZuIigTt8T85s23Rsudj8gp1GcyY6W2e21twA79aYpATY8+/9VV8at8eLrw
i5UQ3ZsT1hnsY2ndy50qXh2kZbpVCTI/0qnYbFrdrT7ZZ5xI2sRI1fNNat70xEjS
6mMjAIMdn2Kn/gXouDRnjMFruspepGpHuvDxgzYs31S+YEvp94JB0oTFomoDHRun
rJyHC2Kzvy05Vfjul1DEvetE+YG5eNYyOltIA8R0v8uECHsukPgQmTnSzUrqqrwR
k8JqC1oKvCzaq7z0w8Pwx6QiIzdiCb6i5lurJIGMIeVKVVstDZoKkweVJ1o9ayRh
InUheVuWqF2AitR6F+62FH/OcVn8voWSrODQxq5oXtqqyuDRQC4GtnpM7EFksK5+
0+djyo0FTIS94oYjlGKPckxou5P2xqYFJxus6dxaeAUiwOsJSqkY3OQQhlCAQIm1
wrPVRbRFpc6Js7cpDw8wCXAZNAWrCDpUF0fVjGacCW6e+CH9uIFXq9lYt5lak3dv
HWjoVw3fRbjhZDsequznxCqr2l2VbjbnaJD1elVg/U+ztp2/0Gg1f2lPEftMdQSj
XL/B6GENxDUWe4UAx5YZTYWkHDEFqyIlMEKhZCnzMyUj7jCztXsCAwEAAaAAMA0G
CSqGSIb3DQEBCwUAA4ICAQBWZgoSw7JO5gaIziRqRqXPzxN+TLHps4ryYKyO31+F
VvoC7mAhdUbVSEHEXRTQckIdlwnaYPAIeoWCQCZHDcvA3BbW5TC/KLoPCsJH/zhI
OeoB2C3QDAifplNjZ/Una4tMyN4jOXDiwW2UKoCtjraXAyLI89q48k5e06xnTYpc
zX23F/mZhheZoeaidqbdRtPemGDQg9KRp99f7ER10OqP5Les7TwVa9xZlyAg/ef8
40sRVH+pPkYY14AccsPrGMr6dSphcPy1koQUp2ov6aUMJbDVs+sinoqBc8ixicLq
AX+lLs/CZmf0LBjAdzg1P29R/tPS76zPv6bRUpp49H9sd/fJONR+6lgq3tSkvd+s
MM9OK7zbs+1GUIiYEbCTdYe7UqSh6wfWfg7qrncWlLWFz+P6Yp7N+92hisDuDwTM
en8fOG5029aqnq+SodYnfD8Idh+9YTza8S1qKi3u4Vf7PKsEr/0byAnm1rybOxyI
PGGQ+H6kRQ+gCgZlD0NpVoOZvD3qriN0vxGSQUnsceMYAvRaf7v8i2FcaqsK6oK8
YFnjpgxeY7Oowv5zEbeXJiqxLJBMj0AJYg8TUxkQofWKyZBEcxzeTzCQbkc4Dr0E
6hqAqbAss6trTJXWOh4Ir3izT9Zb4oT+4i6u1NVxqou6dAWlqeh98dPBmh98Uy5q
Ww==
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,9 @@
# !/bin/sh
# Use localhost as common name.
openssl genrsa -out private/webclient.key.pem 4096
openssl req -sha256 -config openssl.cnf -new -days 3650 -key private/webclient.key.pem -out csrs/webclient.csr.pem
openssl ca -config openssl.cnf -keyfile private/ca.key.pem -cert certs/ca.crt.pem -extensions usr_cert -notext -md sha256 -in csrs/webclient.csr.pem -days 3650 -out certs/webclient.crt.pem
openssl ca -keyfile private/ca.key.pem -cert certs/ca.crt.pem -gencrl -out crl/crl.pem
openssl ca -config openssl.cnf -keyfile private/ca.key.pem -cert certs/ca.crt.pem -crldays 3650 -gencrl -out crl/crl.pem
openssl req -config openssl.cnf -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout private/apache.key -config server.csr.cnf
openssl x509 -req -in server.csr -CA certs/ca.crt.pem -CAkey private/ca.key.pem -CAcreateserial -out certs/apache.crt -days 3650 -sha256 -extfile v3.ext

View file

View file

@ -0,0 +1,348 @@
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
# Policies used by the TSA examples.
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = /opt/ca # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several certs with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extensions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
crl_extensions = crl_ext
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = default # use public key default MD
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extensions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
# utf8only: only UTF8Strings (PKIX recommendation after 2004).
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
string_mask = utf8only
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = EE
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Harjumaa
localityName = Locality Name (eg, city)
localityName_default = Tallinn
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Eesti Interneti Sihtasutus
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
#organizationalUnitName_default =
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
emailAddress = Email Address
emailAddress_default = hello@internet.ee
emailAddress_max = 64
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This is required for TSA certificates.
# extendedKeyUsage = critical,timeStamping
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always
[ proxy_cert_ext ]
# These extensions should be added when creating a proxy certificate
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This really needs to be in place for it to be a proxy certificate.
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
####################################################################
[ tsa ]
default_tsa = tsa_config1 # the default TSA section
[ tsa_config1 ]
# These are used by the TSA reply generation only.
dir = /opt/ca # TSA root directory
serial = $dir/tsaserial # The current serial number (mandatory)
crypto_device = builtin # OpenSSL engine to use for signing
signer_cert = $dir/tsacert.pem # The TSA signing certificate
# (optional)
certs = $dir/cacert.pem # Certificate chain to include in reply
# (optional)
signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
signer_digest = sha256 # Signing digest to use. (Optional)
default_policy = tsa_policy1 # Policy if request did not specify it
# (optional)
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory)
accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
clock_precision_digits = 0 # number of digits after dot. (optional)
ordering = yes # Is ordering defined for timestamps?
# (optional, default: no)
tsa_name = yes # Must the TSA name be included in the reply?
# (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included?
# (optional, default: no)

View file

@ -0,0 +1,8 @@
# Prepare required files
touch index.txt
echo 1000 > serial
echo 1000 > crlnumber
# Generate Root CA.
openssl genrsa -aes256 -out private/ca.key.pem 4096
openssl req -config openssl.cnf -new -x509 -days 365 -key private/ca.key.pem -sha256 -extensions v3_ca -out certs/ca.crt.pem

View file

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCqhksikVH3psjD
GT0a/NN5Oew8ylMn98j5JZdCHlR+UAgbvgeX5oFb6TyMhn5XHBfCfu7Bjt9216a7
0LMKpgrimpmDXrwgQLTRWd4LuCJ9oxaAF38M2K/cVp82lOKF0xmtmLzEski43Dxc
toN5sZCut85bDUJ7C6b8wlogWcgG22wGr6MXAq0An1GA2DpSXbE4amq2suZTbUeY
jOb2Gpt5pYg0hfVANULZlZ2BVeCgQgP9EtRzwD6uJVR1orMb2QKu27MY7w+FegXk
Ela2ysBxgVB6/eNVEqmVIWHCGKOHYxjXioDbXCx40wXv59IKOG68SibGnM1BIfRQ
AMdbSnXvAgMBAAECggEASSYcevKdl7+a5V4hQT9tM9ZuCVG9RCrdskq2zO0Xz6tj
HwtwVG/T0+qER7+12IY7hvpOTweLwn4VjwGinBHIH5az/Y+Y4bkAF8IWJy7Q1NYt
47qwjIEzRzB9UbuiREfe/wHDEBluaqZG2nqMgZpy9w/v3E0e1IuWEV0JrlD1JkMs
nW3RC2unrHjB1ySIdyV6otd/EOHkyd73fygjkA96sVLnv/olyaiW4n7Hlqn1j4it
5Zuqdcaf/AqP+2ADPK+QeISEGYLM9dUeuBEYONkaEH7h5G0ojuxNz5cU7n6l0Hu7
mWOhJFOgA/KRZVsHf+VsPOLGUizY5TjnIS0gyq/wQQKBgQDRkx7ufhYqa81PgQ9X
r0D+D7NuJJxNxA7unU42fa86FWpjnBIxz8tlPM302g+cR6qSWygXcEaxr1CezkcX
db/4MaiN3NWst7z2/dkOEO5Bv+54SzckxZt1QhkoUznxDMOqPdWIKIgjQEroIlHz
TyHT+oF+zEBrNqKGexS11IYczwKBgQDQTKj4C0yfyuXIjwnhEJFqMFqGJsFD/mbL
ca6mx5i/0tsN/HKCSWPza7gh0wiP28f1EULk2UkScHqvt5XBCDofPbr3bkipGy0V
6x2NlOcdCMiFfcK15AIMMddiL9Be1pSTqUIQ1thUu4k0vfbu8LurchZIqjBtWaQK
nrYNI5Oc4QKBgFR5+iDmQCcPVy3x9u5AXXFLgOcn6L1MBzzVub4rQWOnWEAYnBjq
CrGfJeHJuDslhDMEfY+dGVHsOhIZUfy54Qy5b5jnaFX7pjblMgYCexeTtxtULkEr
SjOk1iE0EwoAPCq2TAlbVSzocIlLtD7gKeGZe3NR/7F3z2Fn4Xw902VvAoGBAMQd
GQ0IXmkn97Yfbha3qaFHy0L45AdnU1MCQoSF8bvRAysk3o7qGC/L4H4AGdSQAbAr
Q0cBiLnSqsAb4ePvIgHd9dUVwVVt38H+LkHpyrrcVSbR4+uqs37VwkqQZ+eSsipg
NnJyRRVpx+GfZQlMH/VoIbDig1vBBSB2k0LFlyohAoGBAIwt5E07ez+B0JihGE7F
390gH57xS3M7G4iB1bEr4VyZmStOzNmA4hhz+pz8pnKxMu1bwZdsgvtmQDh59j3I
AUaldDULGfSLQ5YJZ1apyAk2kIDF0Buhe2UtkHtnWG6PFSwEs0AKZeliyIpgZ9R4
86eWGoSuHznP2faVslscZSyE
-----END PRIVATE KEY-----

View file

@ -0,0 +1,54 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,AEB2DBECCB8452DE1D6E3F46B4AD32A8
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
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1 @@
1000

View file

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIC2DCCAcACAQAwgZIxCzAJBgNVBAYTAkVFMREwDwYDVQQIDAhIYXJqdW1hYTEQ
MA4GA1UEBwwHVGFsbGlubjEZMBcGA1UECgwQRWVzdGlJbnRlcm5ldGlTQTEQMA4G
A1UECwwHQXJlbmR1czEgMB4GCSqGSIb3DQEJARYRaGVsbG9AaW50ZXJuZXQuZWUx
DzANBgNVBAMMBioudGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AKqGSyKRUfemyMMZPRr803k57DzKUyf3yPkll0IeVH5QCBu+B5fmgVvpPIyGflcc
F8J+7sGO33bXprvQswqmCuKamYNevCBAtNFZ3gu4In2jFoAXfwzYr9xWnzaU4oXT
Ga2YvMSySLjcPFy2g3mxkK63zlsNQnsLpvzCWiBZyAbbbAavoxcCrQCfUYDYOlJd
sThqaray5lNtR5iM5vYam3mliDSF9UA1QtmVnYFV4KBCA/0S1HPAPq4lVHWisxvZ
Aq7bsxjvD4V6BeQSVrbKwHGBUHr941USqZUhYcIYo4djGNeKgNtcLHjTBe/n0go4
brxKJsaczUEh9FAAx1tKde8CAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQAkJkKR
jqptkp2vkHUH/Nnmqh9SCPD5wETGtGLZzS/ZnWAyRPHZ8Kw3XnCvyZj41EnWifWC
+0kKSpQTvhED8RPmgfE1piQtSPuFJ9f26vyag5sGPfUkBaBl6zaxpK3fDHpCercy
N5J6b1FAoWj/rhtRCMJx8OYCmurBp4BUtyYbduk0FWhdcX8uyRiLOOxaGO7ZpkEf
CEUhEarperXPqhm9NtNbPrEP15tunf5otM6FjpIoc0wFtlOUdrZBT9dE+67F8WlT
qlXUSXucrhWt/WXEiuzaj6w/J7prDr9ua/xO9qUo5aWA6QlPsSsaQl9KF9ST0qXG
hm/lggFVtkCvKv5L
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,14 @@
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[dn]
C=EE
ST=Harjumaa
L=Tallinn
O=EestiInternetiSA
OU=Arendus
emailAddress=hello@internet.ee
CN = *.test

View file

@ -0,0 +1,8 @@
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = test
DNS.2 = registry.test

View file

@ -77,26 +77,6 @@ request_from_map(#{command := Command,
cookies = [Cookie], headers = Headers, cookies = [Cookie], headers = Headers,
epp_verb = Command}, epp_verb = Command},
lager:info("Request from map: [~p]~n", [Request]), lager:info("Request from map: [~p]~n", [Request]),
Request;
request_from_map(#{command := Command,
session_id := SessionId, raw_frame := RawFrame,
common_name := CommonName, client_cert := ClientCert,
peer_ip := PeerIp, cl_trid := ClTRID}) ->
URL = epp_router:route_request(Command),
RequestMethod = epp_router:request_method(Command),
Cookie = hackney_cookie:setcookie("session", SessionId,
[]),
Body = request_body(Command, RawFrame, ClTRID),
Headers = [{"SSL_CLIENT_CERT", ClientCert},
{"SSL_CLIENT_S_DN_CN", CommonName},
{"User-Agent", <<"EPP proxy">>},
{"X-Forwarded-for", epp_util:readable_ip(PeerIp)}],
Request = #epp_request{url = URL,
method = RequestMethod, payload = Body,
cookies = [Cookie], headers = Headers,
epp_verb = Command},
lager:info("Unified Request from map: [~p]~n",
[Request]),
Request. Request.
%% Return form data or an empty list. %% Return form data or an empty list.

View file

@ -68,23 +68,23 @@ create_worker(Socket) ->
ca_cert_file() -> ca_cert_file() ->
case application:get_env(epp_proxy, cacertfile_path) of case application:get_env(epp_proxy, cacertfile_path) of
undefined -> undefined; undefined -> undefined;
{ok, CaCertFile} -> CaCertFile {ok, CaCertFile} -> epp_util:path_for_file(CaCertFile)
end. end.
cert_file() -> cert_file() ->
case application:get_env(epp_proxy, certfile_path) of case application:get_env(epp_proxy, certfile_path) of
undefined -> undefined; undefined -> undefined;
{ok, CertFile} -> CertFile {ok, CertFile} -> epp_util:path_for_file(CertFile)
end. end.
key_file() -> key_file() ->
case application:get_env(epp_proxy, keyfile_path) of case application:get_env(epp_proxy, keyfile_path) of
undefined -> undefined; undefined -> undefined;
{ok, KeyFile} -> KeyFile {ok, KeyFile} -> epp_util:path_for_file(KeyFile)
end. end.
crl_file() -> crl_file() ->
case application:get_env(epp_proxy, crlfile_path) of case application:get_env(epp_proxy, crlfile_path) of
undefined -> undefined; undefined -> undefined;
{ok, CrlFile} -> CrlFile {ok, CrlFile} -> epp_util:path_for_file(CrlFile)
end. end.

View file

@ -2,7 +2,8 @@
-export([create_map/1, create_session_id/1, -export([create_map/1, create_session_id/1,
frame_length/1, frame_length_to_receive/1, frame_length/1, frame_length_to_receive/1,
frame_length_to_send/1, readable_ip/1, session_id/1]). frame_length_to_send/1, path_for_file/1, readable_ip/1,
session_id/1]).
-define(OFFSET, 4). -define(OFFSET, 4).
@ -67,3 +68,11 @@ readable_ip({FirstOctet, SecondOctet, ThirdOctet,
integer_to_list(FourthOctet)], integer_to_list(FourthOctet)],
Binary = list_to_binary(List), Binary = list_to_binary(List),
Binary. Binary.
path_for_file(Filename) ->
case filename:pathtype(Filename) of
absolute -> Filename;
relative ->
CWD = code:priv_dir(epp_proxy),
filename:join(CWD, Filename)
end.

View file

@ -1,36 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIGWzCCBEOgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgaoxCzAJBgNVBAYTAkVF
MREwDwYDVQQIDAhIYXJqdW1hYTEQMA4GA1UEBwwHVGFsbGlubjEjMCEGA1UECgwa
RWVzdGkgSW50ZXJuZXRpIFNpaHRhc3V0dXMxLzAtBgNVBAMMJk1hY2llaidzIGRl
dmVsb3BtZW50IGNlcnRpZmljYXRlIChFSVMpMSAwHgYJKoZIhvcNAQkBFhFoZWxs
b0BpbnRlcm5ldC5lZTAeFw0xOTA1MjMxMjUwMzFaFw0yMDA1MjIxMjUwMzFaMIGp
MQswCQYDVQQGEwJFRTERMA8GA1UECAwISGFyanVtYWExIzAhBgNVBAoMGkVlc3Rp
IEludGVybmV0aSBTaWh0YXN1dHVzMSMwIQYDVQQLDBpFUFAgUHJveHkgdGVzdCBj
ZXJ0aWZpY2F0ZTEXMBUGA1UEAwwORXBwIFByb3h5IFRlc3QxJDAiBgkqhkiG9w0B
CQEWFWVwcC1wcm94eUBpbnRlcm5ldC5lZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
ADCCAgoCggIBAMQalaRFIgknGeQ5iuoBju+cviOksq85azQRIwDaxwwjpFwmRwt2
smPa/0GMyG3/FBGNpUBtb+0ngVMCw5h4aUeWhs9Y9d1kMqaEgpdLm0hWpUIIqOMO
wQpHugPQGJiz75Y4tIUbdazODTvEChDNPZ7Ut8jVzsoRFIgPV4abcoqTqD0wNYZb
TQ0MzOulB2PsxzKrT9MzWkdyju3FYtDxXRGKP3vXC3YhN4EXLqoDzMU51NoYQcPc
Fk5j+1aQKXfNwJcLEvHGlHce9MIEakl5sJt+u8REmp43uy//DNa7mzACfu4xHAW+
heuH+xhEZAT40oxFi0Goa2rhMjz7hx5GM8KPFvJ0vlkR74pRnz1/XNqpx5PundYY
RK0swk+E+z3oFqClsjFiBVZQSPnYdGhid3qDaSqTsVO4G07rzh54SrBm7AsU8CQF
45OOngr1razw5jKnWH6qzNLFKcZBchOSmW31ZpTqfbol6UhThEM6qZr5Dsk+QZbd
kVZ5v3YZs72HL5Fxn/Ix5WOL886fSBOOHyg9rkFoypXZxfyZZehbhY3alszqJFbj
bJ4f+tt2+ObCbkUiN3huP+i+41l+eIBobtsaQhtdzp/44KWR5u4kk2OexO4oZPFN
futAsemo/sxU8E9KvjS02j2zIXTNyV/8Axp30LhHFQvey8QtNbhM2YClAgMBAAGj
gYkwgYYwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwLAYJYIZIAYb4QgENBB8WHU9w
ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSec3EaCPVAovnz
u01SwyEoc9Kt6zAfBgNVHSMEGDAWgBRF1wL+I61d2uBQ1467prsu2SYRGTANBgkq
hkiG9w0BAQsFAAOCAgEAPks4fHoAvzjidw8aJB+nX1pDzbWEbeWOl4xvYizvCN/c
rWeFp6+BnaUuQK5lXTS1z9m2bf70sSFOFTl6JHbpYdU7xr5Qfn69gfdIqeC2k52g
R29oYYRQSjMxufHW9IMufJ/FL1PW6EIlahx01WWla/wg6EC3Bygvnz5oCsDaNTwO
eWKSFVwnE1l6kOoxSparvOdrKpbqvmhUGy8qCRwvLtF2CRQihYSHnnU18oe78REP
Hkyqfjr/GxHn8senKJcN9AQ4RjxMeH/X1wr7Z+0OTpQh61AMEzzyO9sHy9uvxQoN
FREhTs53T10Br5Ppx7hp9S6jmiYgL8wtJwJIWFowq87VfuyeqEKhFXqjybeAXIlv
o4dpUd3woW5rBWhmo6tVs04vNtD6LFktbgkRIV8PPeb1M4QkJ8eD6z7tJNEHVGmK
S0vlDrdTzERwJlhh52d7a6vPXGG1/S7Mji/xyyDuWClaoJXy5NVr8DnKb1WudAXH
nspSoh4YApK4oWTKxYWuhs7rshxFu5A2T03RzJbgsAA/9wrZ4BZz4OCtEVUYoIhV
Qv4f2eOKB8d//vYJWon4R6ukYDZZnYNGplmxl47rzcEam1K88IeaBLN1hirvb9G9
Xk+wDNgZwJmHtYeJSOZHjiQCl2YJCiVn4gbuDxjrEJvye4s6n8fdn4sv2kX06MU=
-----END CERTIFICATE-----

View file

@ -1,51 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View file

@ -1,13 +1,79 @@
-module(epp_certs_SUITE). -module(epp_certs_SUITE).
-include_lib("common_test/include/ct.hrl"). -include_lib("public_key/include/public_key.hrl").
-export([all/0]). -export([all/0]).
-export([run_eunit/1]). -export([der_certificate_test_case/1, subject_from_otp_certificate_test_case/1,
common_name_from_subject_test_case/1]).
all() -> [run_eunit]. all() -> [der_certificate_test_case, subject_from_otp_certificate_test_case,
common_name_from_subject_test_case].
%% Run Unit tests. %% Run Unit tests.
%% Todo: these should be property tests, not unit tests. %% Todo: these should be property tests, not unit tests.
run_eunit(_Config) -> der_certificate_test_case(_Config) ->
ok = eunit:test(epp_certs_tests). PemEntries = public_key:pem_decode(certificate_pem()),
{value, CertEntry} = lists:keysearch('Certificate', 1, PemEntries),
{_, DerCert, _} = CertEntry,
Certificate = epp_certs:der_certificate(DerCert),
true = is_record(Certificate, 'OTPCertificate'),
ok.
subject_from_otp_certificate_test_case(_Config) ->
Certificate = test_certificate(),
Subject = epp_certs:subject_from_otp_certificate(Certificate),
{rdnSequence, _ListOfAttributes} = Subject,
ok.
common_name_from_subject_test_case(_Config) ->
Certificate = test_certificate(),
Subject = epp_certs:subject_from_otp_certificate(Certificate),
CommonName = epp_certs:common_name_from_subject(Subject),
<<"Epp Proxy Test">> = CommonName,
ok.
%% Helper functions
test_certificate() ->
PemEntries = public_key:pem_decode(certificate_pem()),
{value, CertEntry} = lists:keysearch('Certificate', 1, PemEntries),
{_, DerCert, _} = CertEntry,
Decoded = public_key:pkix_decode_cert(DerCert, otp),
Decoded.
certificate_pem() ->
<<"-----BEGIN CERTIFICATE-----\n"
"MIIGWzCCBEOgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgaoxCzAJBgNVBAYTAkVF\n"
"MREwDwYDVQQIDAhIYXJqdW1hYTEQMA4GA1UEBwwHVGFsbGlubjEjMCEGA1UECgwa\n"
"RWVzdGkgSW50ZXJuZXRpIFNpaHRhc3V0dXMxLzAtBgNVBAMMJk1hY2llaidzIGRl\n"
"dmVsb3BtZW50IGNlcnRpZmljYXRlIChFSVMpMSAwHgYJKoZIhvcNAQkBFhFoZWxs\n"
"b0BpbnRlcm5ldC5lZTAeFw0xOTA1MjMxMjUwMzFaFw0yMDA1MjIxMjUwMzFaMIGp\n"
"MQswCQYDVQQGEwJFRTERMA8GA1UECAwISGFyanVtYWExIzAhBgNVBAoMGkVlc3Rp\n"
"IEludGVybmV0aSBTaWh0YXN1dHVzMSMwIQYDVQQLDBpFUFAgUHJveHkgdGVzdCBj\n"
"ZXJ0aWZpY2F0ZTEXMBUGA1UEAwwORXBwIFByb3h5IFRlc3QxJDAiBgkqhkiG9w0B\n"
"CQEWFWVwcC1wcm94eUBpbnRlcm5ldC5lZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP\n"
"ADCCAgoCggIBAMQalaRFIgknGeQ5iuoBju+cviOksq85azQRIwDaxwwjpFwmRwt2\n"
"smPa/0GMyG3/FBGNpUBtb+0ngVMCw5h4aUeWhs9Y9d1kMqaEgpdLm0hWpUIIqOMO\n"
"wQpHugPQGJiz75Y4tIUbdazODTvEChDNPZ7Ut8jVzsoRFIgPV4abcoqTqD0wNYZb\n"
"TQ0MzOulB2PsxzKrT9MzWkdyju3FYtDxXRGKP3vXC3YhN4EXLqoDzMU51NoYQcPc\n"
"Fk5j+1aQKXfNwJcLEvHGlHce9MIEakl5sJt+u8REmp43uy//DNa7mzACfu4xHAW+\n"
"heuH+xhEZAT40oxFi0Goa2rhMjz7hx5GM8KPFvJ0vlkR74pRnz1/XNqpx5PundYY\n"
"RK0swk+E+z3oFqClsjFiBVZQSPnYdGhid3qDaSqTsVO4G07rzh54SrBm7AsU8CQF\n"
"45OOngr1razw5jKnWH6qzNLFKcZBchOSmW31ZpTqfbol6UhThEM6qZr5Dsk+QZbd\n"
"kVZ5v3YZs72HL5Fxn/Ix5WOL886fSBOOHyg9rkFoypXZxfyZZehbhY3alszqJFbj\n"
"bJ4f+tt2+ObCbkUiN3huP+i+41l+eIBobtsaQhtdzp/44KWR5u4kk2OexO4oZPFN\n"
"futAsemo/sxU8E9KvjS02j2zIXTNyV/8Axp30LhHFQvey8QtNbhM2YClAgMBAAGj\n"
"gYkwgYYwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwLAYJYIZIAYb4QgENBB8WHU9w\n"
"ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSec3EaCPVAovnz\n"
"u01SwyEoc9Kt6zAfBgNVHSMEGDAWgBRF1wL+I61d2uBQ1467prsu2SYRGTANBgkq\n"
"hkiG9w0BAQsFAAOCAgEAPks4fHoAvzjidw8aJB+nX1pDzbWEbeWOl4xvYizvCN/c\n"
"rWeFp6+BnaUuQK5lXTS1z9m2bf70sSFOFTl6JHbpYdU7xr5Qfn69gfdIqeC2k52g\n"
"R29oYYRQSjMxufHW9IMufJ/FL1PW6EIlahx01WWla/wg6EC3Bygvnz5oCsDaNTwO\n"
"eWKSFVwnE1l6kOoxSparvOdrKpbqvmhUGy8qCRwvLtF2CRQihYSHnnU18oe78REP\n"
"Hkyqfjr/GxHn8senKJcN9AQ4RjxMeH/X1wr7Z+0OTpQh61AMEzzyO9sHy9uvxQoN\n"
"FREhTs53T10Br5Ppx7hp9S6jmiYgL8wtJwJIWFowq87VfuyeqEKhFXqjybeAXIlv\n"
"o4dpUd3woW5rBWhmo6tVs04vNtD6LFktbgkRIV8PPeb1M4QkJ8eD6z7tJNEHVGmK\n"
"S0vlDrdTzERwJlhh52d7a6vPXGG1/S7Mji/xyyDuWClaoJXy5NVr8DnKb1WudAXH\n"
"nspSoh4YApK4oWTKxYWuhs7rshxFu5A2T03RzJbgsAA/9wrZ4BZz4OCtEVUYoIhV\n"
"Qv4f2eOKB8d//vYJWon4R6ukYDZZnYNGplmxl47rzcEam1K88IeaBLN1hirvb9G9\n"
"Xk+wDNgZwJmHtYeJSOZHjiQCl2YJCiVn4gbuDxjrEJvye4s6n8fdn4sv2kX06MU=\n"
"-----END CERTIFICATE-----">>.

View file

@ -1,67 +0,0 @@
-module(epp_certs_tests).
-include_lib("eunit/include/eunit.hrl").
-include_lib("public_key/include/public_key.hrl").
der_certificate_test() ->
PemEntries = public_key:pem_decode(certificate_pem()),
{value, CertEntry} = lists:keysearch('Certificate', 1, PemEntries),
{_, DerCert, _} = CertEntry,
Certificate = epp_certs:der_certificate(DerCert),
?assert(is_record(Certificate, 'OTPCertificate')).
subject_from_otp_certificate_test() ->
Certificate = test_certificate(),
Subject = epp_certs:subject_from_otp_certificate(Certificate),
{rdnSequence, _ListOfAttributes} = Subject.
common_name_from_subject_test() ->
Certificate = test_certificate(),
Subject = epp_certs:subject_from_otp_certificate(Certificate),
CommonName = epp_certs:common_name_from_subject(Subject),
?assertEqual(<<"Epp Proxy Test">>, CommonName).
test_certificate() ->
PemEntries = public_key:pem_decode(certificate_pem()),
{value, CertEntry} = lists:keysearch('Certificate', 1, PemEntries),
{_, DerCert, _} = CertEntry,
Decoded = public_key:pkix_decode_cert(DerCert, otp),
Decoded.
certificate_pem() ->
<<"-----BEGIN CERTIFICATE-----\n"
"MIIGWzCCBEOgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgaoxCzAJBgNVBAYTAkVF\n"
"MREwDwYDVQQIDAhIYXJqdW1hYTEQMA4GA1UEBwwHVGFsbGlubjEjMCEGA1UECgwa\n"
"RWVzdGkgSW50ZXJuZXRpIFNpaHRhc3V0dXMxLzAtBgNVBAMMJk1hY2llaidzIGRl\n"
"dmVsb3BtZW50IGNlcnRpZmljYXRlIChFSVMpMSAwHgYJKoZIhvcNAQkBFhFoZWxs\n"
"b0BpbnRlcm5ldC5lZTAeFw0xOTA1MjMxMjUwMzFaFw0yMDA1MjIxMjUwMzFaMIGp\n"
"MQswCQYDVQQGEwJFRTERMA8GA1UECAwISGFyanVtYWExIzAhBgNVBAoMGkVlc3Rp\n"
"IEludGVybmV0aSBTaWh0YXN1dHVzMSMwIQYDVQQLDBpFUFAgUHJveHkgdGVzdCBj\n"
"ZXJ0aWZpY2F0ZTEXMBUGA1UEAwwORXBwIFByb3h5IFRlc3QxJDAiBgkqhkiG9w0B\n"
"CQEWFWVwcC1wcm94eUBpbnRlcm5ldC5lZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP\n"
"ADCCAgoCggIBAMQalaRFIgknGeQ5iuoBju+cviOksq85azQRIwDaxwwjpFwmRwt2\n"
"smPa/0GMyG3/FBGNpUBtb+0ngVMCw5h4aUeWhs9Y9d1kMqaEgpdLm0hWpUIIqOMO\n"
"wQpHugPQGJiz75Y4tIUbdazODTvEChDNPZ7Ut8jVzsoRFIgPV4abcoqTqD0wNYZb\n"
"TQ0MzOulB2PsxzKrT9MzWkdyju3FYtDxXRGKP3vXC3YhN4EXLqoDzMU51NoYQcPc\n"
"Fk5j+1aQKXfNwJcLEvHGlHce9MIEakl5sJt+u8REmp43uy//DNa7mzACfu4xHAW+\n"
"heuH+xhEZAT40oxFi0Goa2rhMjz7hx5GM8KPFvJ0vlkR74pRnz1/XNqpx5PundYY\n"
"RK0swk+E+z3oFqClsjFiBVZQSPnYdGhid3qDaSqTsVO4G07rzh54SrBm7AsU8CQF\n"
"45OOngr1razw5jKnWH6qzNLFKcZBchOSmW31ZpTqfbol6UhThEM6qZr5Dsk+QZbd\n"
"kVZ5v3YZs72HL5Fxn/Ix5WOL886fSBOOHyg9rkFoypXZxfyZZehbhY3alszqJFbj\n"
"bJ4f+tt2+ObCbkUiN3huP+i+41l+eIBobtsaQhtdzp/44KWR5u4kk2OexO4oZPFN\n"
"futAsemo/sxU8E9KvjS02j2zIXTNyV/8Axp30LhHFQvey8QtNbhM2YClAgMBAAGj\n"
"gYkwgYYwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwLAYJYIZIAYb4QgENBB8WHU9w\n"
"ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSec3EaCPVAovnz\n"
"u01SwyEoc9Kt6zAfBgNVHSMEGDAWgBRF1wL+I61d2uBQ1467prsu2SYRGTANBgkq\n"
"hkiG9w0BAQsFAAOCAgEAPks4fHoAvzjidw8aJB+nX1pDzbWEbeWOl4xvYizvCN/c\n"
"rWeFp6+BnaUuQK5lXTS1z9m2bf70sSFOFTl6JHbpYdU7xr5Qfn69gfdIqeC2k52g\n"
"R29oYYRQSjMxufHW9IMufJ/FL1PW6EIlahx01WWla/wg6EC3Bygvnz5oCsDaNTwO\n"
"eWKSFVwnE1l6kOoxSparvOdrKpbqvmhUGy8qCRwvLtF2CRQihYSHnnU18oe78REP\n"
"Hkyqfjr/GxHn8senKJcN9AQ4RjxMeH/X1wr7Z+0OTpQh61AMEzzyO9sHy9uvxQoN\n"
"FREhTs53T10Br5Ppx7hp9S6jmiYgL8wtJwJIWFowq87VfuyeqEKhFXqjybeAXIlv\n"
"o4dpUd3woW5rBWhmo6tVs04vNtD6LFktbgkRIV8PPeb1M4QkJ8eD6z7tJNEHVGmK\n"
"S0vlDrdTzERwJlhh52d7a6vPXGG1/S7Mji/xyyDuWClaoJXy5NVr8DnKb1WudAXH\n"
"nspSoh4YApK4oWTKxYWuhs7rshxFu5A2T03RzJbgsAA/9wrZ4BZz4OCtEVUYoIhV\n"
"Qv4f2eOKB8d//vYJWon4R6ukYDZZnYNGplmxl47rzcEam1K88IeaBLN1hirvb9G9\n"
"Xk+wDNgZwJmHtYeJSOZHjiQCl2YJCiVn4gbuDxjrEJvye4s6n8fdn4sv2kX06MU=\n"
"-----END CERTIFICATE-----">>.

View file

@ -0,0 +1,81 @@
-module(epp_http_client_SUITE).
-include("epp_proxy.hrl").
-include_lib("common_test/include/ct.hrl").
-export([all/0]).
-export([init_per_suite/1, end_per_suite/1]).
-export([hello_request_builder_test_case/1,
error_request_builder_test_case/1,
command_request_builder_test_case/1,
registry_unreachable_test_case/1]).
all() ->
[hello_request_builder_test_case,
error_request_builder_test_case,
command_request_builder_test_case,
registry_unreachable_test_case].
init_per_suite(Config) ->
application:ensure_all_started(hackney),
Config.
end_per_suite(Config) ->
application:stop(hackney),
Config.
hello_request_builder_test_case(_Config) ->
RequestMap = #{command => "hello", session_id => "Random",
cl_trid => "EE-123456789", raw_frame => "",
headers => [{"User-Agent", <<"EPP proxy">>}]},
Request = epp_http_client:request_builder(RequestMap),
ExpectedTuple = {epp_request,get,"http://localhost:9292/session/hello",
[],
[<<"session=Random; Version=1">>],
[{"User-Agent",<<"EPP proxy">>}], "hello"},
true = is_record(Request, epp_request),
ExpectedTuple = Request.
error_request_builder_test_case(_Config) ->
RequestMap = #{command => "error", session_id => "Random",
cl_trid => "EE-123456789", code => <<"2001">>,
message => <<"Expected better XML">>,
headers => [{"User-Agent", <<"EPP proxy">>}]},
Request = epp_http_client:request_builder(RequestMap),
ExpectedTuple = {epp_request,get,"http://localhost:9292/error",
[{<<"code">>,<<"2001">>},
{<<"msg">>,<<"Expected better XML">>},
{<<"clTRID">>,"EE-123456789"}],
[<<"session=Random; Version=1">>],
[{"User-Agent",<<"EPP proxy">>}], "error"},
true = is_record(Request, epp_request),
ExpectedTuple = Request,
ok.
command_request_builder_test_case(_Config) ->
RequestMap = #{command => "create", session_id => "Random",
cl_trid => "EE-123456789", raw_frame => "Some XML here",
headers => [{"User-Agent", <<"EPP proxy">>}]},
Request = epp_http_client:request_builder(RequestMap),
ExpectedTuple = {epp_request,post,
"http://localhost:9292/command/create",
{multipart,
[{<<"raw_frame">>,"Some XML here"},
{<<"clTRID">>,"EE-123456789"}]},
[<<"session=Random; Version=1">>],
[{"User-Agent",<<"EPP proxy">>}], "create"},
true = is_record(Request, epp_request),
ExpectedTuple = Request,
ok.
registry_unreachable_test_case(_Config) ->
Request = {epp_request,
post,
"http://localhost:9999/someurl",
{multipart,
[{<<"raw_frame">>,"Some XML here"},
{<<"clTRID">>,"EE-123456789"}]},
[<<"session=Random; Version=1">>],
[{"User-Agent",<<"EPP proxy">>}], "create"},
{2400, _CannedResponse} = epp_http_client:request(Request),
ok.

View file

@ -1,46 +0,0 @@
-module(epp_http_client_tests).
-include_lib("eunit/include/eunit.hrl").
-include("epp_proxy.hrl").
hello_request_builder_test() ->
RequestMap = #{command => "hello", session_id => "Random",
cl_trid => "EE-123456789", raw_frame => "",
headers => [{"User-Agent", <<"EPP proxy">>}]},
Request = epp_http_client:request_builder(RequestMap),
ExpectedTuple = {epp_request,get,"https://registry.test/epp/session/hello",
[],
[<<"session=Random; Version=1">>],
[{"User-Agent",<<"EPP proxy">>}], "hello"},
?assert(is_record(Request, epp_request)),
?assertEqual(ExpectedTuple, Request).
error_request_builder_test() ->
RequestMap = #{command => "error", session_id => "Random",
cl_trid => "EE-123456789", code => <<"2001">>,
message => <<"Expected better XML">>,
headers => [{"User-Agent", <<"EPP proxy">>}]},
Request = epp_http_client:request_builder(RequestMap),
ExpectedTuple = {epp_request,get,"https://registry.test/epp/error",
[{<<"code">>,<<"2001">>},
{<<"msg">>,<<"Expected better XML">>},
{<<"clTRID">>,"EE-123456789"}],
[<<"session=Random; Version=1">>],
[{"User-Agent",<<"EPP proxy">>}], "error"},
?assert(is_record(Request, epp_request)),
?assertEqual(ExpectedTuple, Request).
command_request_builder_test() ->
RequestMap = #{command => "create", session_id => "Random",
cl_trid => "EE-123456789", raw_frame => "Some XML here",
headers => [{"User-Agent", <<"EPP proxy">>}]},
Request = epp_http_client:request_builder(RequestMap),
ExpectedTuple = {epp_request,post,
"https://registry.test/epp/command/create",
{multipart,
[{<<"raw_frame">>,"Some XML here"},
{<<"clTRID">>,"EE-123456789"}]},
[<<"session=Random; Version=1">>],
[{"User-Agent",<<"EPP proxy">>}], "create"},
?assert(is_record(Request, epp_request)),
?assertEqual(ExpectedTuple, Request).

View file

@ -3,10 +3,83 @@
-include_lib("common_test/include/ct.hrl"). -include_lib("common_test/include/ct.hrl").
-export([all/0]). -export([all/0]).
-export([run_eunit/1]). -export([request_method_test_case/1, hello_url_test_case/1, login_url_test_case/1,
logout_url_test_case/1, check_url_test_case/1, info_url_test_case/1, poll_url_test_case/1,
create_url_test_case/1, delete_url_test_case/1, renew_url_test_case/1,
update_url_test_case/1, transfer_url_test_case/1, error_url_test_case/1]).
all() -> [run_eunit]. all() -> [request_method_test_case, hello_url_test_case, login_url_test_case,
logout_url_test_case, check_url_test_case, info_url_test_case, poll_url_test_case,
create_url_test_case, delete_url_test_case, renew_url_test_case,
update_url_test_case, transfer_url_test_case, error_url_test_case].
%% Run Unit tests %% Run Unit tests
run_eunit(_Config) -> request_method_test_case(_Config) ->
ok = eunit:test(epp_router_tests). get = epp_router:request_method("hello"),
get = epp_router:request_method(<<"hello">>),
get = epp_router:request_method("error"),
get = epp_router:request_method(<<"error">>),
post = epp_router:request_method("create"),
post = epp_router:request_method(123),
ok.
%% TODO: Make less verbose and repetitive
hello_url_test_case(_Config) ->
"http://localhost:9292/session/hello" = epp_router:route_request("hello"),
"http://localhost:9292/session/hello" = epp_router:route_request(<<"hello">>),
ok.
login_url_test_case(_Config) ->
"http://localhost:9292/session/login" = epp_router:route_request("login"),
"http://localhost:9292/session/login" = epp_router:route_request(<<"login">>),
ok.
logout_url_test_case(_Config) ->
"http://localhost:9292/session/logout" = epp_router:route_request("logout"),
"http://localhost:9292/session/logout" = epp_router:route_request(<<"logout">>),
ok.
check_url_test_case(_Config) ->
"http://localhost:9292/command/check" = epp_router:route_request("check"),
"http://localhost:9292/command/check" = epp_router:route_request(<<"check">>),
ok.
info_url_test_case(_Config) ->
"http://localhost:9292/command/info" = epp_router:route_request("info"),
"http://localhost:9292/command/info" = epp_router:route_request(<<"info">>),
ok.
poll_url_test_case(_Config) ->
"http://localhost:9292/command/poll" = epp_router:route_request("poll"),
"http://localhost:9292/command/poll" = epp_router:route_request(<<"poll">>),
ok.
create_url_test_case(_Config) ->
"http://localhost:9292/command/create" = epp_router:route_request("create"),
"http://localhost:9292/command/create" = epp_router:route_request(<<"create">>),
ok.
delete_url_test_case(_Config) ->
"http://localhost:9292/command/delete" = epp_router:route_request("delete"),
"http://localhost:9292/command/delete" = epp_router:route_request(<<"delete">>),
ok.
renew_url_test_case(_Config) ->
"http://localhost:9292/command/renew" = epp_router:route_request("renew"),
"http://localhost:9292/command/renew" = epp_router:route_request(<<"renew">>),
ok.
update_url_test_case(_Config) ->
"http://localhost:9292/command/update" = epp_router:route_request("update"),
"http://localhost:9292/command/update" = epp_router:route_request(<<"update">>),
ok.
transfer_url_test_case(_Config) ->
"http://localhost:9292/command/transfer" = epp_router:route_request("transfer"),
"http://localhost:9292/command/transfer" = epp_router:route_request(<<"transfer">>),
ok.
error_url_test_case(_Config) ->
"http://localhost:9292/error" = epp_router:route_request("error"),
"http://localhost:9292/error" = epp_router:route_request(<<"error">>),
ok.

View file

@ -1,60 +0,0 @@
-module(epp_router_tests).
-include_lib("eunit/include/eunit.hrl").
request_method_test() ->
?assertEqual(get, epp_router:request_method("hello")),
?assertEqual(get, epp_router:request_method(<<"hello">>)),
?assertEqual(get, epp_router:request_method("error")),
?assertEqual(get, epp_router:request_method(<<"error">>)),
?assertEqual(post, epp_router:request_method("create")),
?assertEqual(post, epp_router:request_method(123)).
%% TODO: Make less verbose and repetitive
hello_url_test() ->
?assertEqual("https://registry.test/epp/session/hello", epp_router:route_request("hello")),
?assertEqual("https://registry.test/epp/session/hello", epp_router:route_request(<<"hello">>)).
login_url_test() ->
?assertEqual("https://registry.test/epp/session/login", epp_router:route_request("login")),
?assertEqual("https://registry.test/epp/session/login", epp_router:route_request(<<"login">>)).
logout_url_test() ->
?assertEqual("https://registry.test/epp/session/logout", epp_router:route_request("logout")),
?assertEqual("https://registry.test/epp/session/logout", epp_router:route_request(<<"logout">>)).
check_url_test() ->
?assertEqual("https://registry.test/epp/command/check", epp_router:route_request("check")),
?assertEqual("https://registry.test/epp/command/check", epp_router:route_request(<<"check">>)).
info_url_test() ->
?assertEqual("https://registry.test/epp/command/info", epp_router:route_request("info")),
?assertEqual("https://registry.test/epp/command/info", epp_router:route_request(<<"info">>)).
poll_url_test() ->
?assertEqual("https://registry.test/epp/command/poll", epp_router:route_request("poll")),
?assertEqual("https://registry.test/epp/command/poll", epp_router:route_request(<<"poll">>)).
create_url_test() ->
?assertEqual("https://registry.test/epp/command/create", epp_router:route_request("create")),
?assertEqual("https://registry.test/epp/command/create", epp_router:route_request(<<"create">>)).
delete_url_test() ->
?assertEqual("https://registry.test/epp/command/delete", epp_router:route_request("delete")),
?assertEqual("https://registry.test/epp/command/delete", epp_router:route_request(<<"delete">>)).
renew_url_test() ->
?assertEqual("https://registry.test/epp/command/renew", epp_router:route_request("renew")),
?assertEqual("https://registry.test/epp/command/renew", epp_router:route_request(<<"renew">>)).
update_url_test() ->
?assertEqual("https://registry.test/epp/command/update", epp_router:route_request("update")),
?assertEqual("https://registry.test/epp/command/update", epp_router:route_request(<<"update">>)).
transfer_url_test() ->
?assertEqual("https://registry.test/epp/command/transfer", epp_router:route_request("transfer")),
?assertEqual("https://registry.test/epp/command/transfer", epp_router:route_request(<<"transfer">>)).
error_url_test() ->
?assertEqual("https://registry.test/epp/error", epp_router:route_request("error")),
?assertEqual("https://registry.test/epp/error", epp_router:route_request(<<"error">>)).

View file

@ -3,11 +3,77 @@
-include_lib("common_test/include/ct.hrl"). -include_lib("common_test/include/ct.hrl").
-export([all/0]). -export([all/0]).
-export([run_eunit/1]). -export([session_id_test_case/1,
create_map_test_case/1,
create_session_id_test_case/1,
frame_length_test_case/1,
frame_length_to_receive_test_case/1,
frame_length_to_send_test_case/1,
readable_ip_test_case/1,
path_for_file_test_case/1]).
all() -> [run_eunit]. all() -> [session_id_test_case,
create_map_test_case,
create_session_id_test_case,
frame_length_test_case,
frame_length_to_receive_test_case,
frame_length_to_send_test_case,
readable_ip_test_case,
path_for_file_test_case].
%% Run Unit tests.
%% Todo: these should be property tests, not unit tests. %% Todo: these should be property tests, not unit tests.
run_eunit(_Config) -> session_id_test_case(_Config) ->
ok = eunit:test(epp_util_tests). Pid = spawn(fun () -> ok end),
SessionId = epp_util:session_id(Pid),
true = is_list(SessionId),
true = length(SessionId) > 0,
ok.
create_map_test_case(_Config) ->
Pid = spawn(fun () -> ok end),
Map = epp_util:create_map(Pid),
Pid = maps:get("pid", Map),
true = is_list(maps:get("timestamp", Map)),
true = is_float(maps:get("random", Map)),
ok.
create_session_id_test_case(_Config) ->
Pid = list_to_pid("<0.130.0>"),
Random = 0.7131518292439796,
Time = "2019-05-23T14:47:52+03:00",
Map = #{"pid" => Pid, "random" => Random, "timestamp" => Time},
Hash = epp_util:create_session_id(Map),
true = is_list(Hash),
"88F49C2B1BDD6F2355BF4424A67C928DA7C5616B30F7C5B35F17747348AF61EF8723ED6BE6012D879CB3D6A7EC7A187660A56910ED896AE67DE533C212D" = Hash,
ok.
frame_length_test_case(_Config) ->
2 = epp_util:frame_length("aa"),
2 = epp_util:frame_length(<<"aa">>),
2 = epp_util:frame_length(<<"">>),
ok.
frame_length_to_receive_test_case(_Config) ->
2 = epp_util:frame_length_to_receive(6),
0 = epp_util:frame_length_to_receive(4),
{'EXIT', {function_clause, _}} =
(catch epp_util:frame_length_to_receive(-22)),
ok.
frame_length_to_send_test_case(_Config) ->
18 = epp_util:frame_length_to_send("<epp><command>"),
4 = epp_util:frame_length_to_send(""),
ok.
readable_ip_test_case(_Config) ->
<<"127.0.0.1">> = epp_util:readable_ip({127,0,0,1}),
{'EXIT', {function_clause, _}}
= (catch epp_util:readable_ip({127,0,0,1,0})),
ok.
path_for_file_test_case(_Config) ->
AbsoluteFilename = "/usr/bin",
AbsoluteFilename = epp_util:path_for_file(AbsoluteFilename),
RelativeFilename = "usr/bin",
RelativeFilename =:= epp_util:path_for_file(RelativeFilename),
ok.

View file

@ -1,43 +0,0 @@
-module(epp_util_tests).
-include_lib("eunit/include/eunit.hrl").
session_id_test() ->
Pid = spawn(fun () -> ok end),
SessionId = epp_util:session_id(Pid),
?assert(is_list(SessionId)),
?assert(length(SessionId) > 0).
create_map_test() ->
Pid = spawn(fun () -> ok end),
Map = epp_util:create_map(Pid),
?assertEqual(Pid, maps:get("pid", Map)),
?assert(is_list(maps:get("timestamp", Map))),
?assert(is_float(maps:get("random", Map))).
create_session_id_test() ->
Pid = list_to_pid("<0.130.0>"),
Random = 0.7131518292439796,
Time = "2019-05-23T14:47:52+03:00",
Map = #{"pid" => Pid, "random" => Random, "timestamp" => Time},
Hash = epp_util:create_session_id(Map),
?assert(is_list(Hash)),
?assertEqual("88F49C2B1BDD6F2355BF4424A67C928DA7C5616B30F7C5B35F17747348AF61EF8723ED6BE6012D879CB3D6A7EC7A187660A56910ED896AE67DE533C212D", Hash).
frame_length_test() ->
?assertEqual(2, epp_util:frame_length("aa")),
?assertEqual(2, epp_util:frame_length(<<"aa">>)),
?assertEqual(2, epp_util:frame_length(<<"">>)).
frame_length_to_receive_test() ->
?assertEqual(2, epp_util:frame_length_to_receive(6)),
?assertEqual(0, epp_util:frame_length_to_receive(4)),
?assertError(function_clause, epp_util:frame_length_to_receive(-22)).
frame_length_to_send_test() ->
?assertEqual(18, epp_util:frame_length_to_send("<epp><command>")),
?assertEqual(4, epp_util:frame_length_to_send("")).
readable_ip_test() ->
?assertEqual(<<"127.0.0.1">>, epp_util:readable_ip({127,0,0,1})),
?assertError(function_clause, epp_util:readable_ip({127,0,0,1,0})).

View file

@ -2,11 +2,125 @@
-include_lib("common_test/include/ct.hrl"). -include_lib("common_test/include/ct.hrl").
%% This is required for parse tests.
-include_lib("xmerl/include/xmerl.hrl").
-define(sampleCommandList,
"<epp>
<command>
<login>
<clID>test</clID>
<pw>test</pw>
</login>
<clTRID>sample1trid</clTRID>
</command>
</epp>").
-define(validXMLNotEPPList,
"<user>
<name>test</name>
<email>test@test.com</email>
</user>").
-export([all/0]). -export([all/0]).
-export([run_eunit/1]). -export([parse_not_a_list_or_binary_test_case/1,
parse_sample_valid_xml_binary_test_case/1,
parse_sample_valid_xml_list_test_case/1,
parse_sample_invalid_xml_binary_test_case/1,
parse_sample_invalid_xml_list_test_case/1,
find_cltrid_binary_test_case/1,
find_cltrid_empty_binary_test_case/1,
find_cltrid_empty_list_test_case/1,
find_cltrid_list_test_case/1,
find_cltrid_atom_test_case/1,
get_command_success_test_case/1,
get_command_xml_not_epp_failure_test_case/1,
get_command_failure_test_case/1]).
all() -> [run_eunit]. all() -> [parse_not_a_list_or_binary_test_case,
parse_sample_valid_xml_binary_test_case,
parse_sample_valid_xml_list_test_case,
parse_sample_invalid_xml_binary_test_case,
parse_sample_invalid_xml_list_test_case,
find_cltrid_binary_test_case,
find_cltrid_empty_binary_test_case,
find_cltrid_empty_list_test_case,
find_cltrid_list_test_case,
find_cltrid_atom_test_case,
get_command_success_test_case,
get_command_xml_not_epp_failure_test_case,
get_command_failure_test_case].
%% Run Unit tests parse_not_a_list_or_binary_test_case(_Config) ->
run_eunit(_Config) -> Input = 1234,
ok = eunit:test(epp_xml_tests). ExpectedOutput = {error, {fatal, {expected_binary_or_list}}},
ExpectedOutput = epp_xml:parse(Input),
ok.
parse_sample_valid_xml_list_test_case(_Config) ->
Input = ?sampleCommandList,
{ok, Record} = epp_xml:parse(Input),
true = is_record(Record, xmlElement),
ok.
parse_sample_valid_xml_binary_test_case(_Config) ->
Input = list_to_binary(?sampleCommandList),
{ok, Record} = epp_xml:parse(Input),
true = is_record(Record, xmlElement),
ok.
parse_sample_invalid_xml_list_test_case(_Config) ->
Input = "Some text",
{error, {fatal, _Details}} = epp_xml:parse(Input),
ok.
parse_sample_invalid_xml_binary_test_case(_Config) ->
Input = list_to_binary("Some text"),
{error, {fatal, _Details}} = epp_xml:parse(Input),
ok.
%% find_cltrid
find_cltrid_empty_list_test_case(_Config) ->
Input = "",
nomatch = epp_xml:find_cltrid(Input),
ok.
find_cltrid_list_test_case(_Config) ->
Input = list_to_binary(?sampleCommandList),
<<"sample1trid">> = epp_xml:find_cltrid(Input),
ok.
find_cltrid_empty_binary_test_case(_Config) ->
Input = <<"">>,
nomatch = epp_xml:find_cltrid(Input),
ok.
find_cltrid_binary_test_case(_Config) ->
Input = ?sampleCommandList,
<<"sample1trid">> = epp_xml:find_cltrid(Input),
ok.
find_cltrid_atom_test_case(_Config) ->
Input = atom,
nomatch = epp_xml:find_cltrid(Input),
ok.
%% get_command
get_command_success_test_case(_Config) ->
%% We require an existing xlmElement record to pass around.
{ok, XMLElement} = epp_xml:parse(?sampleCommandList),
Command = epp_xml:get_command(XMLElement),
"login" = Command,
ok.
get_command_xml_not_epp_failure_test_case(_Config) ->
{ok, XMLElement} = epp_xml:parse(?validXMLNotEPPList),
Command = epp_xml:get_command(XMLElement),
undefined = Command,
ok.
get_command_failure_test_case(_Config) ->
%% Can pass any garbage, should get back undefined.,
Command = epp_xml:get_command("Some random string"),
undefined = Command,
ok.

View file

@ -1,80 +0,0 @@
-module(epp_xml_tests).
-include_lib("eunit/include/eunit.hrl").
%% This is required for parse tests.
-include_lib("xmerl/include/xmerl.hrl").
-define(sampleCommandList,
"<epp>
<command>
<login>
<clID>test</clID>
<pw>test</pw>
</login>
<clTRID>sample1trid</clTRID>
</command>
</epp>").
-define(validXMLNotEPPList,
"<user>
<name>test</name>
<email>test@test.com</email>
</user>").
%% parse
parse_not_a_list_or_binary_test() ->
Input = 1234,
ExpectedOutput = {error, {fatal, {expected_binary_or_list}}},
?assertEqual(ExpectedOutput, epp_xml:parse(Input)).
parse_sample_valid_xml_list_test() ->
Input = ?sampleCommandList,
{ok, Record} = epp_xml:parse(Input),
?assert(is_record(Record, xmlElement)).
parse_sample_valid_xml_binary_test() ->
Input = list_to_binary(?sampleCommandList),
{ok, Record} = epp_xml:parse(Input),
?assert(is_record(Record, xmlElement)).
parse_sample_invalid_xml_list_test() ->
Input = "Some text",
{error, {fatal, _Details}} = epp_xml:parse(Input).
parse_sample_invalid_xml_binary_test() ->
Input = list_to_binary("Some text"),
{error, {fatal, _Details}} = epp_xml:parse(Input).
%% find_cltrid
find_cltrid_empty_list_test() ->
Input = "",
?assertEqual(nomatch, epp_xml:find_cltrid(Input)).
find_cltrid_list_test() ->
Input = list_to_binary(?sampleCommandList),
?assertEqual(<<"sample1trid">>, epp_xml:find_cltrid(Input)).
find_cltrid_empty_binary_test() ->
Input = <<"">>,
?assertEqual(nomatch, epp_xml:find_cltrid(Input)).
find_cltrid_binary_test() ->
Input = ?sampleCommandList,
?assertEqual(<<"sample1trid">>, epp_xml:find_cltrid(Input)).
%% get_command
get_command_success_test() ->
%% We require an existing xlmElement record to pass around.
{ok, XMLElement} = epp_xml:parse(?sampleCommandList),
Command = epp_xml:get_command(XMLElement),
?assertEqual("login", Command).
get_command_xml_not_epp_failure_test() ->
{ok, XMLElement} = epp_xml:parse(?validXMLNotEPPList),
Command = epp_xml:get_command(XMLElement),
?assertEqual(undefined, Command).
get_command_failure_test() ->
%% Can pass any garbage, should get back undefined.,
Command = epp_xml:get_command("Some random string"),
?assertEqual(undefined, Command).

View file

@ -0,0 +1,184 @@
-module(tcp_client_SUITE).
-include("epp_proxy.hrl").
-include_lib("common_test/include/ct.hrl").
-export([all/0]).
-export([init_per_suite/1, end_per_suite/1]).
-export([frame_size_test_case/1,
greetings_test_case/1,
session_test_case/1,
valid_command_test_case/1,
invalid_command_test_case/1,
error_test_case/1]).
all() ->
[frame_size_test_case,
greetings_test_case,
session_test_case,
valid_command_test_case,
invalid_command_test_case,
error_test_case].
init_per_suite(Config) ->
application:ensure_all_started(epp_proxy),
application:ensure_all_started(hackney),
Options = [binary,
{active, false}],
[{tcp_options, Options} | Config].
end_per_suite(Config) ->
application:stop(epp_proxy),
application:stop(hackney),
Config.
%% Test Cases
frame_size_test_case(Config) ->
Options = proplists:get_value(tcp_options, Config),
{ok, Socket} = gen_tcp:connect("localhost", 1180, Options, 2000),
{ok, Data} = gen_tcp:recv(Socket, 0, 1200),
true = (byte_size(Data) =:= length_of_data(Data)),
ok.
greetings_test_case(Config) ->
Options = proplists:get_value(tcp_options, Config),
{ok, Socket} = gen_tcp:connect("localhost", 1180, Options, 2000),
Data = receive_data(Socket),
match_data(Data, "<greeting>"),
ok.
session_test_case(Config) ->
Options = proplists:get_value(tcp_options, Config),
{ok, Socket} = gen_tcp:connect("localhost", 1180, Options, 2000),
_Data = receive_data(Socket),
ok = send_data(login_command(), Socket),
LoginResponse = receive_data(Socket),
match_data(LoginResponse, "Command completed successfully"),
match_data(LoginResponse, "ccReg-5886259930"),
LogoutCommand =
<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
"<epp xmlns=\"https://epp.tld.ee/schema/epp-ee-1.0.xsd\">\n"
"<command>\n"
"<logout>\n"
"<clID>test_bestnames</clID>\n"
"<pw>testtest</pw>\n"
"<options>\n"
"<version>1.0</version>\n"
"<lang>en</lang>\n"
"</options>\n"
"<svcs>\n"
"<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>\n"
"<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>\n"
"<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>\n"
"<objURI>urn:ietf:params:xml:ns:keyrelay-1.0</objURI>\n"
"</svcs>\n"
"</logout>\n"
"</command>\n"
"</epp>\n">>,
ok = send_data(LogoutCommand, Socket),
LogoutResponse = receive_data(Socket),
match_data(LogoutResponse,
"Command completed successfully; ending session"),
%% After receiving logout, connection should be closed.
{error, closed} = receive_data(Socket),
ok.
valid_command_test_case(Config) ->
Options = proplists:get_value(tcp_options, Config),
{ok, Socket} = gen_tcp:connect("localhost", 1180, Options, 2000),
_Data = receive_data(Socket),
ok = send_data(login_command(), Socket),
_LoginResponse = receive_data(Socket),
PollCommand =
<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
"<epp xmlns=\"https://epp.tld.ee/schema/epp-ee-1.0.xsd\">\n"
"<command>\n"
"<poll op=\"req\"/>\n"
"<clTRID>foo bar baz</clTRID>\n"
"</command>\n"
"</epp>\n">>,
ok = send_data(PollCommand, Socket),
PollResponse = receive_data(Socket),
match_data(PollResponse,
"Command completed successfully; no messages"),
ok.
%% Sending an invalid command frame should close the connection.
%% It also crashes the process.
invalid_command_test_case(Config) ->
Options = proplists:get_value(tcp_options, Config),
{ok, Socket} = gen_tcp:connect("localhost", 1180, Options, 2000),
_Data = receive_data(Socket),
ok = send_data(login_command(), Socket),
_LoginResponse = receive_data(Socket),
InvalidCommand =
<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
"<epp xmlns=\"https://epp.tld.ee/schema/epp-ee-1.0.xsd\">\n"
"<command>\n"
"<fooo op=\"req\"/>\n"
"<clTRID>foo bar baz</clTRID>\n"
"</command>\n"
"</epp>\n">>,
ok = send_data(InvalidCommand, Socket),
{error, closed} = receive_data(Socket),
ok.
error_test_case(Config) ->
Options = proplists:get_value(tcp_options, Config),
{ok, Socket} = gen_tcp:connect("localhost", 1180, Options, 2000),
_Data = receive_data(Socket),
ok = send_data(login_command(), Socket),
_LoginResponse = receive_data(Socket),
InvalidXml =
<<"</epp>\n">>,
ok = send_data(InvalidXml, Socket),
ErrorResponse = receive_data(Socket),
match_data(ErrorResponse,
"Command syntax error."),
ok.
%% Helper functions:
length_of_data(Data) ->
EPPEnvelope = binary:part(Data, {0, 4}),
ReportedLength = binary:decode_unsigned(EPPEnvelope, big),
ReportedLength.
send_data(Message, Socket) ->
Length = epp_util:frame_length_to_send(Message),
ByteSize = <<Length:32/big>>,
CompleteMessage = <<ByteSize/binary, Message/binary>>,
ok = gen_tcp:send(Socket, CompleteMessage).
receive_data(Socket) ->
case gen_tcp:recv(Socket, 0, 1200) of
{error, Reason} -> {error, Reason};
{ok, Data } ->
EppEnvelope = binary:part(Data, {0, 4}),
ReportedLength = binary:decode_unsigned(EppEnvelope, big),
binary:part(Data, {byte_size(Data), 4 - ReportedLength})
end.
match_data(Data, Pattern) ->
{ok, MatchPattern} = re:compile(Pattern),
{match, _Captured} = re:run(Data, MatchPattern).
login_command() ->
<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
"<epp xmlns=\"https://epp.tld.ee/schema/epp-ee-1.0.xsd\">\n"
"<command>\n"
"<login>\n"
"<clID>test_bestnames</clID>\n"
"<pw>testtest</pw>\n"
"<options>\n"
"<version>1.0</version>\n"
"<lang>en</lang>\n"
"</options>\n"
"<svcs>\n"
"<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>\n"
"<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>\n"
"<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>\n"
"<objURI>urn:ietf:params:xml:ns:keyrelay-1.0</objURI>\n"
"</svcs>\n"
"</login>\n"
"</command>\n"
"</epp>\n">>.

View file

@ -0,0 +1,187 @@
-module(tls_client_SUITE).
-include("epp_proxy.hrl").
-include_lib("common_test/include/ct.hrl").
-export([all/0]).
-export([init_per_suite/1, end_per_suite/1]).
-export([frame_size_test_case/1,
greetings_test_case/1,
session_test_case/1,
valid_command_test_case/1,
invalid_command_test_case/1,
error_test_case/1]).
all() ->
[frame_size_test_case,
greetings_test_case,
session_test_case,
valid_command_test_case,
invalid_command_test_case,
error_test_case].
init_per_suite(Config) ->
application:ensure_all_started(epp_proxy),
application:ensure_all_started(hackney),
CWD = code:priv_dir(epp_proxy),
Options = [binary,
{certfile, filename:join(CWD, "test_ca/certs/webclient.crt.pem")},
{keyfile, filename:join(CWD, "test_ca/private/webclient.key.pem")},
{active, false}],
[{ssl_options, Options} | Config].
end_per_suite(Config) ->
application:stop(epp_proxy),
application:stop(hackney),
Config.
%% Test Cases
frame_size_test_case(Config) ->
Options = proplists:get_value(ssl_options, Config),
{ok, Socket} = ssl:connect("localhost", 1443, Options, 2000),
{ok, Data} = ssl:recv(Socket, 0, 1200),
true = (byte_size(Data) =:= length_of_data(Data)),
ok.
greetings_test_case(Config) ->
Options = proplists:get_value(ssl_options, Config),
{ok, Socket} = ssl:connect("localhost", 1443, Options, 2000),
Data = receive_data(Socket),
match_data(Data, "<greeting>"),
ok.
session_test_case(Config) ->
Options = proplists:get_value(ssl_options, Config),
{ok, Socket} = ssl:connect("localhost", 1443, Options, 2000),
_Data = receive_data(Socket),
ok = send_data(login_command(), Socket),
LoginResponse = receive_data(Socket),
match_data(LoginResponse, "Command completed successfully"),
match_data(LoginResponse, "ccReg-5886259930"),
LogoutCommand =
<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
"<epp xmlns=\"https://epp.tld.ee/schema/epp-ee-1.0.xsd\">\n"
"<command>\n"
"<logout>\n"
"<clID>test_bestnames</clID>\n"
"<pw>testtest</pw>\n"
"<options>\n"
"<version>1.0</version>\n"
"<lang>en</lang>\n"
"</options>\n"
"<svcs>\n"
"<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>\n"
"<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>\n"
"<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>\n"
"<objURI>urn:ietf:params:xml:ns:keyrelay-1.0</objURI>\n"
"</svcs>\n"
"</logout>\n"
"</command>\n"
"</epp>\n">>,
ok = send_data(LogoutCommand, Socket),
LogoutResponse = receive_data(Socket),
match_data(LogoutResponse,
"Command completed successfully; ending session"),
%% After receiving logout, connection should be closed.
{error, closed} = receive_data(Socket),
ok.
valid_command_test_case(Config) ->
Options = proplists:get_value(ssl_options, Config),
{ok, Socket} = ssl:connect("localhost", 1443, Options, 2000),
_Data = receive_data(Socket),
ok = send_data(login_command(), Socket),
_LoginResponse = receive_data(Socket),
PollCommand =
<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
"<epp xmlns=\"https://epp.tld.ee/schema/epp-ee-1.0.xsd\">\n"
"<command>\n"
"<poll op=\"req\"/>\n"
"<clTRID>foo bar baz</clTRID>\n"
"</command>\n"
"</epp>\n">>,
ok = send_data(PollCommand, Socket),
PollResponse = receive_data(Socket),
match_data(PollResponse,
"Command completed successfully; no messages"),
ok.
%% Sending an invalid command frame should close the connection.
%% It also crashes the process.
invalid_command_test_case(Config) ->
Options = proplists:get_value(ssl_options, Config),
{ok, Socket} = ssl:connect("localhost", 1443, Options, 2000),
_Data = receive_data(Socket),
ok = send_data(login_command(), Socket),
_LoginResponse = receive_data(Socket),
InvalidCommand =
<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
"<epp xmlns=\"https://epp.tld.ee/schema/epp-ee-1.0.xsd\">\n"
"<command>\n"
"<fooo op=\"req\"/>\n"
"<clTRID>foo bar baz</clTRID>\n"
"</command>\n"
"</epp>\n">>,
ok = send_data(InvalidCommand, Socket),
{error, closed} = receive_data(Socket),
ok.
error_test_case(Config) ->
Options = proplists:get_value(ssl_options, Config),
{ok, Socket} = ssl:connect("localhost", 1443, Options, 2000),
_Data = receive_data(Socket),
ok = send_data(login_command(), Socket),
_LoginResponse = receive_data(Socket),
InvalidXml =
<<"</epp>\n">>,
ok = send_data(InvalidXml, Socket),
ErrorResponse = receive_data(Socket),
match_data(ErrorResponse,
"Command syntax error."),
ok.
%% Helper functions:
length_of_data(Data) ->
EPPEnvelope = binary:part(Data, {0, 4}),
ReportedLength = binary:decode_unsigned(EPPEnvelope, big),
ReportedLength.
send_data(Message, Socket) ->
Length = epp_util:frame_length_to_send(Message),
ByteSize = <<Length:32/big>>,
CompleteMessage = <<ByteSize/binary, Message/binary>>,
ok = ssl:send(Socket, CompleteMessage).
receive_data(Socket) ->
case ssl:recv(Socket, 0, 1200) of
{error, Reason} -> {error, Reason};
{ok, Data } ->
EppEnvelope = binary:part(Data, {0, 4}),
ReportedLength = binary:decode_unsigned(EppEnvelope, big),
binary:part(Data, {byte_size(Data), 4 - ReportedLength})
end.
match_data(Data, Pattern) ->
{ok, MatchPattern} = re:compile(Pattern),
{match, _Captured} = re:run(Data, MatchPattern).
login_command() ->
<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
"<epp xmlns=\"https://epp.tld.ee/schema/epp-ee-1.0.xsd\">\n"
"<command>\n"
"<login>\n"
"<clID>test_bestnames</clID>\n"
"<pw>testtest</pw>\n"
"<options>\n"
"<version>1.0</version>\n"
"<lang>en</lang>\n"
"</options>\n"
"<svcs>\n"
"<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>\n"
"<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>\n"
"<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>\n"
"<objURI>urn:ietf:params:xml:ns:keyrelay-1.0</objURI>\n"
"</svcs>\n"
"</login>\n"
"</command>\n"
"</epp>\n">>.

View file

@ -3,9 +3,9 @@
{dev_mode, true}, {dev_mode, true},
{tcp_port, 3333}, {tcp_port, 3333},
{tls_port, 700}, {tls_port, 700},
{epp_session_url, "http://httpd:3000/epp/session/"}, {epp_session_url, "http://epp:3000/epp/session/"},
{epp_command_url, "http://httpd:3000/epp/command/"}, {epp_command_url, "http://epp:3000/epp/command/"},
{epp_error_url, "http://httpd:3000/epp/error/"}, {epp_error_url, "http://epp:3000/epp/error/"},
{cacertfile_path, "/opt/ca/certs/ca.crt.pem"}, {cacertfile_path, "/opt/ca/certs/ca.crt.pem"},
{certfile_path, "/opt/ca/certs/apache.crt"}, {certfile_path, "/opt/ca/certs/apache.crt"},
{keyfile_path, "/opt/ca/private/apache.key"}, {keyfile_path, "/opt/ca/private/apache.key"},

View file

@ -1,11 +1,22 @@
[ [
{epp_proxy, [{dev_mode, false}, {epp_proxy, [{dev_mode, true},
{tcp_port, 3333}, {tcp_port, 1180},
{tls_port, 4444}, {tls_port, 1443},
{epp_session_url, "https://registry.test/epp/session/"},
{epp_command_url, "https://registry.test/epp/command/"}, {epp_session_url, "http://localhost:9292/session/"},
{epp_error_url, "https://registry.test/epp/error/"}, {epp_command_url, "http://localhost:9292/command/"},
{cacertfile_path, "/opt/shared/ca/certs/ca.crt.pem"}, {epp_error_url, "http://localhost:9292/error/"},
{certfile_path, "/opt/shared/ca/certs/apache.crt"}, %% Path to root CA that should check the client certificates.
{keyfile_path, "/opt/shared/ca/private/apache.key"}]} {cacertfile_path, "test_ca/certs/ca.crt.pem"},
{certfile_path, "test_ca/certs/apache.crt"},
{keyfile_path, "test_ca/private/apache.key"},
{crlfile_path, "test_ca/crl/crl.pem"}]},
{lager, [
{handlers, [
{lager_console_backend, [{level, warning}]}
%% {lager_syslog_backend, ["epp_proxy", local0, debug]}
]}
]}
]. ].