wj_eventmachine 1.3.0.dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +179 -0
- data/GNU +281 -0
- data/LICENSE +60 -0
- data/README.md +110 -0
- data/docs/DocumentationGuidesIndex.md +27 -0
- data/docs/GettingStarted.md +520 -0
- data/docs/old/ChangeLog +211 -0
- data/docs/old/DEFERRABLES +246 -0
- data/docs/old/EPOLL +141 -0
- data/docs/old/INSTALL +13 -0
- data/docs/old/KEYBOARD +42 -0
- data/docs/old/LEGAL +25 -0
- data/docs/old/LIGHTWEIGHT_CONCURRENCY +130 -0
- data/docs/old/PURE_RUBY +75 -0
- data/docs/old/RELEASE_NOTES +94 -0
- data/docs/old/SMTP +4 -0
- data/docs/old/SPAWNED_PROCESSES +148 -0
- data/docs/old/TODO +8 -0
- data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
- data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
- data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
- data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
- data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
- data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
- data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
- data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
- data/examples/old/ex_channel.rb +43 -0
- data/examples/old/ex_queue.rb +2 -0
- data/examples/old/ex_tick_loop_array.rb +15 -0
- data/examples/old/ex_tick_loop_counter.rb +32 -0
- data/examples/old/helper.rb +2 -0
- data/ext/binder.cpp +124 -0
- data/ext/binder.h +52 -0
- data/ext/cmain.cpp +1046 -0
- data/ext/ed.cpp +2238 -0
- data/ext/ed.h +460 -0
- data/ext/em.cpp +2378 -0
- data/ext/em.h +266 -0
- data/ext/eventmachine.h +152 -0
- data/ext/extconf.rb +285 -0
- data/ext/fastfilereader/extconf.rb +120 -0
- data/ext/fastfilereader/mapper.cpp +214 -0
- data/ext/fastfilereader/mapper.h +59 -0
- data/ext/fastfilereader/rubymain.cpp +126 -0
- data/ext/kb.cpp +79 -0
- data/ext/page.cpp +107 -0
- data/ext/page.h +51 -0
- data/ext/pipe.cpp +354 -0
- data/ext/project.h +174 -0
- data/ext/rubymain.cpp +1610 -0
- data/ext/ssl.cpp +627 -0
- data/ext/ssl.h +103 -0
- data/ext/wait_for_single_fd.h +36 -0
- data/java/.classpath +8 -0
- data/java/.project +17 -0
- data/java/src/com/rubyeventmachine/EmReactor.java +625 -0
- data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
- data/java/src/com/rubyeventmachine/EmReactorInterface.java +70 -0
- data/java/src/com/rubyeventmachine/EventableChannel.java +72 -0
- data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +201 -0
- data/java/src/com/rubyeventmachine/EventableSocketChannel.java +415 -0
- data/java/src/com/rubyeventmachine/NullEmReactor.java +157 -0
- data/java/src/com/rubyeventmachine/NullEventableChannel.java +81 -0
- data/lib/em/buftok.rb +59 -0
- data/lib/em/callback.rb +58 -0
- data/lib/em/channel.rb +69 -0
- data/lib/em/completion.rb +307 -0
- data/lib/em/connection.rb +776 -0
- data/lib/em/deferrable.rb +210 -0
- data/lib/em/deferrable/pool.rb +2 -0
- data/lib/em/file_watch.rb +73 -0
- data/lib/em/future.rb +61 -0
- data/lib/em/io_streamer.rb +68 -0
- data/lib/em/iterator.rb +252 -0
- data/lib/em/messages.rb +66 -0
- data/lib/em/pool.rb +151 -0
- data/lib/em/process_watch.rb +45 -0
- data/lib/em/processes.rb +123 -0
- data/lib/em/protocols.rb +37 -0
- data/lib/em/protocols/header_and_content.rb +138 -0
- data/lib/em/protocols/httpclient.rb +303 -0
- data/lib/em/protocols/httpclient2.rb +602 -0
- data/lib/em/protocols/line_and_text.rb +125 -0
- data/lib/em/protocols/line_protocol.rb +33 -0
- data/lib/em/protocols/linetext2.rb +179 -0
- data/lib/em/protocols/memcache.rb +331 -0
- data/lib/em/protocols/object_protocol.rb +46 -0
- data/lib/em/protocols/postgres3.rb +246 -0
- data/lib/em/protocols/saslauth.rb +175 -0
- data/lib/em/protocols/smtpclient.rb +394 -0
- data/lib/em/protocols/smtpserver.rb +666 -0
- data/lib/em/protocols/socks4.rb +66 -0
- data/lib/em/protocols/stomp.rb +205 -0
- data/lib/em/protocols/tcptest.rb +54 -0
- data/lib/em/pure_ruby.rb +1299 -0
- data/lib/em/queue.rb +80 -0
- data/lib/em/resolver.rb +232 -0
- data/lib/em/spawnable.rb +84 -0
- data/lib/em/streamer.rb +118 -0
- data/lib/em/threaded_resource.rb +90 -0
- data/lib/em/tick_loop.rb +85 -0
- data/lib/em/timers.rb +61 -0
- data/lib/em/version.rb +3 -0
- data/lib/eventmachine.rb +1602 -0
- data/lib/jeventmachine.rb +318 -0
- data/rakelib/package.rake +120 -0
- data/rakelib/test.rake +6 -0
- data/rakelib/test_pure.rake +11 -0
- data/tests/client.crt +31 -0
- data/tests/client.key +51 -0
- data/tests/dhparam.pem +13 -0
- data/tests/em_ssl_handlers.rb +153 -0
- data/tests/em_test_helper.rb +198 -0
- data/tests/jruby/test_jeventmachine.rb +38 -0
- data/tests/test_attach.rb +199 -0
- data/tests/test_basic.rb +321 -0
- data/tests/test_channel.rb +75 -0
- data/tests/test_completion.rb +178 -0
- data/tests/test_connection_count.rb +83 -0
- data/tests/test_connection_write.rb +35 -0
- data/tests/test_defer.rb +35 -0
- data/tests/test_deferrable.rb +35 -0
- data/tests/test_epoll.rb +141 -0
- data/tests/test_error_handler.rb +38 -0
- data/tests/test_exc.rb +37 -0
- data/tests/test_file_watch.rb +86 -0
- data/tests/test_fork.rb +75 -0
- data/tests/test_futures.rb +170 -0
- data/tests/test_handler_check.rb +35 -0
- data/tests/test_hc.rb +155 -0
- data/tests/test_httpclient.rb +238 -0
- data/tests/test_httpclient2.rb +132 -0
- data/tests/test_idle_connection.rb +31 -0
- data/tests/test_inactivity_timeout.rb +102 -0
- data/tests/test_io_streamer.rb +47 -0
- data/tests/test_ipv4.rb +96 -0
- data/tests/test_ipv6.rb +107 -0
- data/tests/test_iterator.rb +122 -0
- data/tests/test_kb.rb +28 -0
- data/tests/test_keepalive.rb +113 -0
- data/tests/test_line_protocol.rb +33 -0
- data/tests/test_ltp.rb +155 -0
- data/tests/test_ltp2.rb +332 -0
- data/tests/test_many_fds.rb +21 -0
- data/tests/test_next_tick.rb +104 -0
- data/tests/test_object_protocol.rb +36 -0
- data/tests/test_pause.rb +109 -0
- data/tests/test_pending_connect_timeout.rb +52 -0
- data/tests/test_pool.rb +196 -0
- data/tests/test_process_watch.rb +50 -0
- data/tests/test_processes.rb +128 -0
- data/tests/test_proxy_connection.rb +180 -0
- data/tests/test_pure.rb +156 -0
- data/tests/test_queue.rb +64 -0
- data/tests/test_resolver.rb +129 -0
- data/tests/test_running.rb +14 -0
- data/tests/test_sasl.rb +46 -0
- data/tests/test_send_file.rb +217 -0
- data/tests/test_servers.rb +32 -0
- data/tests/test_shutdown_hooks.rb +23 -0
- data/tests/test_smtpclient.rb +75 -0
- data/tests/test_smtpserver.rb +90 -0
- data/tests/test_sock_opt.rb +53 -0
- data/tests/test_spawn.rb +290 -0
- data/tests/test_ssl_args.rb +41 -0
- data/tests/test_ssl_dhparam.rb +57 -0
- data/tests/test_ssl_ecdh_curve.rb +57 -0
- data/tests/test_ssl_extensions.rb +24 -0
- data/tests/test_ssl_methods.rb +31 -0
- data/tests/test_ssl_protocols.rb +190 -0
- data/tests/test_ssl_verify.rb +52 -0
- data/tests/test_stomp.rb +38 -0
- data/tests/test_system.rb +46 -0
- data/tests/test_threaded_resource.rb +68 -0
- data/tests/test_tick_loop.rb +58 -0
- data/tests/test_timers.rb +150 -0
- data/tests/test_ud.rb +8 -0
- data/tests/test_unbind_reason.rb +40 -0
- metadata +384 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'em_test_helper'
|
|
4
|
+
require 'tempfile'
|
|
5
|
+
|
|
6
|
+
class TestSSLArgs < Test::Unit::TestCase
|
|
7
|
+
|
|
8
|
+
require_relative 'em_ssl_handlers'
|
|
9
|
+
include EMSSLHandlers
|
|
10
|
+
|
|
11
|
+
def test_tls_params_file_doesnt_exist
|
|
12
|
+
priv_file, cert_file = 'foo_priv_key', 'bar_cert_file'
|
|
13
|
+
[priv_file, cert_file].all? do |f|
|
|
14
|
+
assert(!File.exist?(f), "Cert file #{f} seems to exist, and should not for the tests")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
assert_raises EM::FileNotFoundException do
|
|
18
|
+
client_server client: { private_key_file: priv_file }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
assert_raises EM::FileNotFoundException do
|
|
22
|
+
client_server client: { cert_chain_file: cert_file }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
assert_raises EM::FileNotFoundException do
|
|
26
|
+
client_server client: { private_key_file: priv_file, cert_chain_file: cert_file }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def _test_tls_params_file_improper
|
|
31
|
+
priv_file_path = Tempfile.new('em_test').path
|
|
32
|
+
cert_file_path = Tempfile.new('em_test').path
|
|
33
|
+
params = { private_key_file: priv_file_path,
|
|
34
|
+
cert_chain_file: cert_file_path }
|
|
35
|
+
begin
|
|
36
|
+
client_server client: params
|
|
37
|
+
rescue Object
|
|
38
|
+
assert false, 'should not have raised an exception'
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end if EM.ssl?
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'em_test_helper'
|
|
4
|
+
|
|
5
|
+
class TestSSLDhParam < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
require_relative 'em_ssl_handlers'
|
|
8
|
+
include EMSSLHandlers
|
|
9
|
+
|
|
10
|
+
DH_PARAM_FILE = File.join(__dir__, 'dhparam.pem')
|
|
11
|
+
|
|
12
|
+
DH_1_2 = { cipher_list: "DHE,EDH", ssl_version: %w(TLSv1_2) }
|
|
13
|
+
CLIENT_1_2 = { client_unbind: true, ssl_version: %w(TLSv1_2) }
|
|
14
|
+
|
|
15
|
+
def test_no_dhparam
|
|
16
|
+
omit_if(EM.library_type == :pure_ruby) # DH will work with defaults
|
|
17
|
+
omit_if(rbx?)
|
|
18
|
+
|
|
19
|
+
client_server client: CLIENT_1_2, server: DH_1_2
|
|
20
|
+
|
|
21
|
+
refute Client.handshake_completed?
|
|
22
|
+
refute Server.handshake_completed?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def test_dhparam_1_2
|
|
26
|
+
omit_if(rbx?)
|
|
27
|
+
|
|
28
|
+
client_server client: CLIENT_1_2, server: DH_1_2.merge(dhparam: DH_PARAM_FILE)
|
|
29
|
+
|
|
30
|
+
assert Client.handshake_completed?
|
|
31
|
+
assert Server.handshake_completed?
|
|
32
|
+
|
|
33
|
+
assert Client.cipher_name.length > 0
|
|
34
|
+
assert_equal Client.cipher_name, Server.cipher_name
|
|
35
|
+
|
|
36
|
+
assert_match(/^(DHE|EDH)/, Client.cipher_name)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_dhparam_1_3
|
|
40
|
+
omit_if(rbx?)
|
|
41
|
+
omit("TLSv1_3 is unavailable") unless EM.const_defined? :EM_PROTO_TLSv1_3
|
|
42
|
+
|
|
43
|
+
client = { client_unbind: true, ssl_version: %w(TLSv1_3) }
|
|
44
|
+
server = { dhparam: DH_PARAM_FILE, cipher_list: "DHE,EDH", ssl_version: %w(TLSv1_3) }
|
|
45
|
+
client_server client: client, server: server
|
|
46
|
+
|
|
47
|
+
assert Client.handshake_completed?
|
|
48
|
+
assert Server.handshake_completed?
|
|
49
|
+
|
|
50
|
+
assert Client.cipher_name.length > 0
|
|
51
|
+
assert_equal Client.cipher_name, Server.cipher_name
|
|
52
|
+
|
|
53
|
+
# see https://wiki.openssl.org/index.php/TLS1.3#Ciphersuites
|
|
54
|
+
# may depend on OpenSSL build options
|
|
55
|
+
assert_equal "TLS_AES_256_GCM_SHA384", Client.cipher_name
|
|
56
|
+
end
|
|
57
|
+
end if EM.ssl?
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'em_test_helper'
|
|
4
|
+
|
|
5
|
+
class TestSSLEcdhCurve < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
require_relative 'em_ssl_handlers'
|
|
8
|
+
include EMSSLHandlers
|
|
9
|
+
|
|
10
|
+
def test_no_ecdh_curve
|
|
11
|
+
omit_if(rbx?)
|
|
12
|
+
omit("OpenSSL 1.1.x (and later) auto selects curve") if IS_SSL_GE_1_1
|
|
13
|
+
|
|
14
|
+
client_server server: { cipher_list: "ECDH", ssl_version: %w(TLSv1_2) }
|
|
15
|
+
|
|
16
|
+
refute Client.handshake_completed?
|
|
17
|
+
refute Server.handshake_completed?
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_ecdh_curve_tlsv1_2
|
|
21
|
+
omit_if(EM.library_type == :pure_ruby && RUBY_VERSION < "2.3.0")
|
|
22
|
+
omit_if(rbx?)
|
|
23
|
+
|
|
24
|
+
server = { cipher_list: "ECDH", ssl_version: %w(TLSv1_2) }
|
|
25
|
+
server.merge!(ecdh_curve: "prime256v1") unless IS_SSL_GE_1_1
|
|
26
|
+
|
|
27
|
+
client_server server: server
|
|
28
|
+
|
|
29
|
+
assert Client.handshake_completed?
|
|
30
|
+
assert Server.handshake_completed?
|
|
31
|
+
|
|
32
|
+
assert Client.cipher_name.length > 0
|
|
33
|
+
assert_equal Client.cipher_name, Server.cipher_name
|
|
34
|
+
|
|
35
|
+
assert_match(/^(AECDH|ECDHE)/, Client.cipher_name)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_ecdh_curve_tlsv1_3
|
|
39
|
+
omit_if(EM.library_type == :pure_ruby && RUBY_VERSION < "2.3.0")
|
|
40
|
+
omit_if(rbx?)
|
|
41
|
+
omit("TLSv1_3 is unavailable") unless EM.const_defined? :EM_PROTO_TLSv1_3
|
|
42
|
+
|
|
43
|
+
tls = { cipher_list: "ECDH", ssl_version: %w(TLSv1_3) }
|
|
44
|
+
|
|
45
|
+
client_server server: tls
|
|
46
|
+
|
|
47
|
+
assert Client.handshake_completed?
|
|
48
|
+
assert Server.handshake_completed?
|
|
49
|
+
|
|
50
|
+
assert Client.cipher_name.length > 0
|
|
51
|
+
assert_equal Client.cipher_name, Server.cipher_name
|
|
52
|
+
|
|
53
|
+
# see https://wiki.openssl.org/index.php/TLS1.3#Ciphersuites
|
|
54
|
+
# may depend on OpenSSL build options
|
|
55
|
+
assert_equal "TLS_AES_256_GCM_SHA384", Client.cipher_name
|
|
56
|
+
end
|
|
57
|
+
end if EM.ssl?
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'em_test_helper'
|
|
4
|
+
|
|
5
|
+
class TestSSLExtensions < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
require_relative 'em_ssl_handlers'
|
|
8
|
+
include EMSSLHandlers
|
|
9
|
+
|
|
10
|
+
def test_tlsext_sni_hostname_1_2
|
|
11
|
+
client = { sni_hostname: 'example.com', ssl_version: %w(TLSv1_2) }
|
|
12
|
+
client_server client: client
|
|
13
|
+
assert Server.handshake_completed?
|
|
14
|
+
assert_equal 'example.com', Server.sni_hostname
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_tlsext_sni_hostname_1_3
|
|
18
|
+
omit("TLSv1_3 is unavailable") unless EM.const_defined? :EM_PROTO_TLSv1_3
|
|
19
|
+
client = { sni_hostname: 'example.com', ssl_version: %w(TLSv1_3) }
|
|
20
|
+
client_server client: client
|
|
21
|
+
assert Server.handshake_completed?
|
|
22
|
+
assert_equal 'example.com', Server.sni_hostname
|
|
23
|
+
end
|
|
24
|
+
end if EM.ssl?
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'em_test_helper'
|
|
4
|
+
|
|
5
|
+
class TestSSLMethods < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
require_relative 'em_ssl_handlers'
|
|
8
|
+
include EMSSLHandlers
|
|
9
|
+
|
|
10
|
+
def test_ssl_methods
|
|
11
|
+
omit_if(rbx?)
|
|
12
|
+
|
|
13
|
+
client_server
|
|
14
|
+
|
|
15
|
+
assert Server.handshake_completed?
|
|
16
|
+
assert Client.handshake_completed?
|
|
17
|
+
|
|
18
|
+
assert Server.cert_value.is_a? NilClass
|
|
19
|
+
assert Client.cert_value.is_a? String
|
|
20
|
+
|
|
21
|
+
assert Client.cipher_bits > 0
|
|
22
|
+
assert_equal Client.cipher_bits, Server.cipher_bits
|
|
23
|
+
|
|
24
|
+
assert Client.cipher_name.length > 0
|
|
25
|
+
assert_match(/AES/, Client.cipher_name)
|
|
26
|
+
assert_equal Client.cipher_name, Server.cipher_name
|
|
27
|
+
|
|
28
|
+
assert Client.cipher_protocol.start_with? "TLS"
|
|
29
|
+
assert_equal Client.cipher_protocol, Server.cipher_protocol
|
|
30
|
+
end
|
|
31
|
+
end if EM.ssl?
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'em_test_helper'
|
|
4
|
+
|
|
5
|
+
# For OpenSSL 1.1.0 and later, cipher_protocol returns single cipher, older
|
|
6
|
+
# versions return "TLSv1/SSLv3"
|
|
7
|
+
# TLSv1.1 handshake_completed Server/Client callback order is reversed from
|
|
8
|
+
# older protocols
|
|
9
|
+
|
|
10
|
+
class TestSSLProtocols < Test::Unit::TestCase
|
|
11
|
+
|
|
12
|
+
require_relative 'em_ssl_handlers'
|
|
13
|
+
include EMSSLHandlers
|
|
14
|
+
|
|
15
|
+
# We're checking for whether Context min_version= & max_version= are defined, but
|
|
16
|
+
# JRuby has a bug where they're defined, but the private method they call isn't
|
|
17
|
+
RUBY_SSL_GE_2_1 = OpenSSL::SSL::SSLContext.private_instance_methods(false).include?(:set_minmax_proto_version)
|
|
18
|
+
|
|
19
|
+
def test_invalid_ssl_version
|
|
20
|
+
assert_raises(RuntimeError, "Unrecognized SSL/TLS Version: badinput") do
|
|
21
|
+
client = { ssl_version: %w(tlsv1 badinput) }
|
|
22
|
+
server = { ssl_version: %w(tlsv1 badinput) }
|
|
23
|
+
client_server client: client, server: server
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_any_to_v3
|
|
28
|
+
omit("SSLv3 is (correctly) unavailable") if EM::OPENSSL_NO_SSL3
|
|
29
|
+
client_server client: TLS_ALL, server: SSL_3
|
|
30
|
+
assert Client.handshake_completed?
|
|
31
|
+
assert Server.handshake_completed?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_any_to_tlsv1_2
|
|
35
|
+
client_server client: TLS_ALL, server: TLS_1_2
|
|
36
|
+
assert Client.handshake_completed?
|
|
37
|
+
assert Server.handshake_completed?
|
|
38
|
+
if IS_SSL_GE_1_1
|
|
39
|
+
assert_equal "TLSv1.2", Client.cipher_protocol
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def test_case_insensitivity
|
|
44
|
+
lower_case = SSL_AVAIL.map { |p| p.downcase }
|
|
45
|
+
client = { ssl_version: %w(tlsv1_2) }
|
|
46
|
+
server = { ssl_version: lower_case }
|
|
47
|
+
client_server client: client, server: server
|
|
48
|
+
assert Client.handshake_completed?
|
|
49
|
+
assert Server.handshake_completed?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_v3_to_any
|
|
53
|
+
omit("SSLv3 is (correctly) unavailable") if EM::OPENSSL_NO_SSL3
|
|
54
|
+
client_server client: SSL_3, server: TLS_ALL
|
|
55
|
+
assert Client.handshake_completed?
|
|
56
|
+
assert Server.handshake_completed?
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_tlsv1_2_to_any
|
|
60
|
+
client_server client: TLS_1_2, server: TLS_ALL
|
|
61
|
+
assert Client.handshake_completed?
|
|
62
|
+
assert Server.handshake_completed?
|
|
63
|
+
if IS_SSL_GE_1_1
|
|
64
|
+
assert_equal "TLSv1.2", Server.cipher_protocol
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def test_v3_to_v3
|
|
69
|
+
omit("SSLv3 is (correctly) unavailable") if EM::OPENSSL_NO_SSL3
|
|
70
|
+
client_server client: SSL_3, server: SSL_3
|
|
71
|
+
assert Client.handshake_completed?
|
|
72
|
+
assert Server.handshake_completed?
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def test_tlsv1_2_to_tlsv1_2
|
|
76
|
+
client_server client: TLS_1_2, server: TLS_1_2
|
|
77
|
+
assert Client.handshake_completed?
|
|
78
|
+
assert Server.handshake_completed?
|
|
79
|
+
if IS_SSL_GE_1_1
|
|
80
|
+
assert_equal "TLSv1.2", Client.cipher_protocol
|
|
81
|
+
assert_equal "TLSv1.2", Server.cipher_protocol
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def test_tlsv1_3_to_tlsv1_3
|
|
86
|
+
omit("TLSv1_3 is unavailable") unless EM.const_defined? :EM_PROTO_TLSv1_3
|
|
87
|
+
client_server client: TLS_1_3, server: TLS_1_3
|
|
88
|
+
assert Client.handshake_completed?
|
|
89
|
+
assert Server.handshake_completed?
|
|
90
|
+
assert_equal "TLSv1.3", Client.cipher_protocol
|
|
91
|
+
assert_equal "TLSv1.3", Server.cipher_protocol
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def test_any_to_any
|
|
95
|
+
client_server client: TLS_ALL, server: TLS_ALL
|
|
96
|
+
assert Client.handshake_completed?
|
|
97
|
+
assert Server.handshake_completed?
|
|
98
|
+
if IS_SSL_GE_1_1
|
|
99
|
+
best_protocol = SSL_AVAIL.last.tr "_", "."
|
|
100
|
+
assert_equal best_protocol, Client.cipher_protocol
|
|
101
|
+
assert_equal best_protocol, Server.cipher_protocol
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def test_default_to_default
|
|
106
|
+
client_server
|
|
107
|
+
assert Client.handshake_completed?
|
|
108
|
+
assert Server.handshake_completed?
|
|
109
|
+
if IS_SSL_GE_1_1
|
|
110
|
+
best_protocol = SSL_AVAIL.last.tr "_", "."
|
|
111
|
+
assert_equal best_protocol, Client.cipher_protocol
|
|
112
|
+
assert_equal best_protocol, Server.cipher_protocol
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def external_client(ext_min, ext_max, ext_ssl, server)
|
|
117
|
+
EM.run do
|
|
118
|
+
# setup_timeout 2
|
|
119
|
+
EM.start_server IP, PORT, Server, server.merge( { stop_after_handshake: true} )
|
|
120
|
+
EM.defer do
|
|
121
|
+
sock = TCPSocket.new IP, PORT
|
|
122
|
+
ctx = OpenSSL::SSL::SSLContext.new
|
|
123
|
+
if RUBY_SSL_GE_2_1
|
|
124
|
+
ctx.min_version = ext_min if ext_min
|
|
125
|
+
ctx.max_version = ext_max if ext_max
|
|
126
|
+
else
|
|
127
|
+
ctx.ssl_version = ext_ssl
|
|
128
|
+
end
|
|
129
|
+
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
|
|
130
|
+
ssl.connect
|
|
131
|
+
ssl.close rescue nil
|
|
132
|
+
sock.close rescue nil
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
assert Server.handshake_completed?
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def test_v3_with_external_client
|
|
139
|
+
omit("SSLv3 is (correctly) unavailable") if EM::OPENSSL_NO_SSL3
|
|
140
|
+
external_client nil, nil, :SSLv3_client, SSL_3
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Fixed Server
|
|
144
|
+
def test_tlsv1_2_with_external_client
|
|
145
|
+
external_client nil, nil, :SSLv23_client, TLS_1_2
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def test_tlsv1_3_with_external_client
|
|
149
|
+
omit("TLSv1_3 is unavailable") unless EM.const_defined?(:EM_PROTO_TLSv1_3) &&
|
|
150
|
+
OpenSSL::SSL.const_defined?(:TLS1_3_VERSION)
|
|
151
|
+
external_client nil, nil, :SSLv23_client, TLS_1_3
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Fixed Client
|
|
155
|
+
def test_any_with_external_client_tlsv1_2
|
|
156
|
+
external_client :TLS1_2, :TLS1_2, :TLSv1_2_client, TLS_ALL
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def test_any_with_external_client_tlsv1_3
|
|
160
|
+
omit("TLSv1_3 is unavailable") unless EM.const_defined? :EM_PROTO_TLSv1_3
|
|
161
|
+
external_client :TLS1_3, :TLS1_3, :TLSv1_2_client, TLS_ALL
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Refuse a client?
|
|
165
|
+
def test_tlsv1_2_required_with_external_client
|
|
166
|
+
EM.run do
|
|
167
|
+
n = 0
|
|
168
|
+
EM.add_periodic_timer(0.5) do
|
|
169
|
+
n += 1
|
|
170
|
+
(EM.stop rescue nil) if n == 2
|
|
171
|
+
end
|
|
172
|
+
EM.start_server IP, PORT, Server, TLS_1_2.merge( { stop_after_handshake: true} )
|
|
173
|
+
EM.defer do
|
|
174
|
+
sock = TCPSocket.new IP, PORT
|
|
175
|
+
ctx = OpenSSL::SSL::SSLContext.new
|
|
176
|
+
if RUBY_SSL_GE_2_1
|
|
177
|
+
ctx.max_version = :TLS1_1
|
|
178
|
+
else
|
|
179
|
+
ctx.ssl_version = :TLSv1_client
|
|
180
|
+
end
|
|
181
|
+
ssl = OpenSSL::SSL::SSLSocket.new sock, ctx
|
|
182
|
+
assert_raise(OpenSSL::SSL::SSLError) { ssl.connect }
|
|
183
|
+
ssl.close rescue nil
|
|
184
|
+
sock.close rescue nil
|
|
185
|
+
EM.stop rescue nil
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
refute Server.handshake_completed?
|
|
189
|
+
end
|
|
190
|
+
end if EM.ssl?
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'em_test_helper'
|
|
4
|
+
|
|
5
|
+
class TestSSLVerify < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
require_relative 'em_ssl_handlers'
|
|
8
|
+
include EMSSLHandlers
|
|
9
|
+
|
|
10
|
+
CERT_FROM_FILE = File.read "#{__dir__}/client.crt"
|
|
11
|
+
|
|
12
|
+
CLIENT_CERT = { private_key_file: "#{__dir__}/client.key",
|
|
13
|
+
cert_chain_file: "#{__dir__}/client.crt" }
|
|
14
|
+
|
|
15
|
+
def test_fail_no_peer_cert
|
|
16
|
+
omit_if(rbx?)
|
|
17
|
+
|
|
18
|
+
server = { verify_peer: true, fail_if_no_peer_cert: true,
|
|
19
|
+
ssl_verify_result: "|RAISE|Verify peer should not get called for a client without a certificate" }
|
|
20
|
+
|
|
21
|
+
client_server Client, Server, server: server
|
|
22
|
+
|
|
23
|
+
refute Client.handshake_completed? unless "TLSv1.3" == Client.cipher_protocol
|
|
24
|
+
refute Server.handshake_completed?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_accept_server
|
|
28
|
+
omit_if(EM.library_type == :pure_ruby) # Server has a default cert chain
|
|
29
|
+
omit_if(rbx?)
|
|
30
|
+
|
|
31
|
+
server = { verify_peer: true, ssl_verify_result: true }
|
|
32
|
+
|
|
33
|
+
client_server Client, Server, client: CLIENT_CERT, server: server
|
|
34
|
+
|
|
35
|
+
assert_equal CERT_FROM_FILE, Server.cert
|
|
36
|
+
assert Client.handshake_completed?
|
|
37
|
+
assert Server.handshake_completed?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_deny_server
|
|
41
|
+
omit_if(EM.library_type == :pure_ruby) # Server has a default cert chain
|
|
42
|
+
omit_if(rbx?)
|
|
43
|
+
|
|
44
|
+
server = { verify_peer: true, ssl_verify_result: false }
|
|
45
|
+
|
|
46
|
+
client_server Client, Server, client: CLIENT_CERT, server: server
|
|
47
|
+
|
|
48
|
+
assert_equal CERT_FROM_FILE, Server.cert
|
|
49
|
+
refute Client.handshake_completed? unless "TLSv1.3" == Client.cipher_protocol
|
|
50
|
+
refute Server.handshake_completed?
|
|
51
|
+
end
|
|
52
|
+
end if EM.ssl?
|