Created
December 13, 2019 14:48
-
-
Save rdp/2b867a5b9e3c0a56368833f2b95878bd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/spec/std/openssl/ssl/socket_spec.cr b/spec/std/openssl/ssl/socket_spec.cr | |
index df3a34a61..b1d931c34 100644 | |
--- a/spec/std/openssl/ssl/socket_spec.cr | |
+++ b/spec/std/openssl/ssl/socket_spec.cr | |
@@ -42,7 +42,7 @@ describe OpenSSL::SSL::Socket do | |
# in tls 1.3, if clients don't read anything and close the connection | |
# the server still try and write to it a ticket, resulting in a "pipe failure" | |
# this context method disables the tickets which allows the behavior: | |
- server_context.disable_session_resume_tickets | |
+ #server_context.disable_session_resume_tickets | |
OpenSSL::SSL::Server.open(tcp_server, server_context) do |server| | |
spawn do | |
@@ -61,7 +61,7 @@ describe OpenSSL::SSL::Socket do | |
it "closes connection to server that doesn't properly terminate SSL session" do | |
tcp_server = TCPServer.new(0) | |
server_context, client_context = ssl_context_pair | |
- server_context.disable_session_resume_tickets # avoid Broken pipe | |
+ #server_context.disable_session_resume_tickets # avoid Broken pipe | |
client_successfully_closed_socket = Channel(Nil).new | |
spawn do | |
@@ -77,4 +77,24 @@ describe OpenSSL::SSL::Socket do | |
socket.close | |
client_successfully_closed_socket.send(nil) | |
end | |
+ | |
+ it "interprets graceful EOF of underlying socket as SSL termination" do | |
+ tcp_server = TCPServer.new(0) | |
+ server_context, client_context = ssl_context_pair | |
+ | |
+ server_finished_reading = Channel(String).new | |
+ spawn do | |
+ OpenSSL::SSL::Server.open(tcp_server, server_context, sync_close: true) do |server| | |
+ server_socket = server.accept | |
+ received = server_socket.gets_to_end # interprets underlying socket close as a graceful EOF | |
+ server_finished_reading.send(received) | |
+ end | |
+ end | |
+ socket = TCPSocket.new(tcp_server.local_address.address, tcp_server.local_address.port) | |
+ socket_ssl = OpenSSL::SSL::Socket::Client.new(socket, client_context, hostname: "example.com", sync_close: true) | |
+ socket_ssl.print "hello" | |
+ socket_ssl.flush # needed today see #5375 | |
+ socket.close # close underlying socket without gracefully shutting down SSL at all | |
+ server_finished_reading.receive().should eq("hello") | |
+ end | |
end | |
diff --git a/src/openssl.cr b/src/openssl.cr | |
index 93b676f6a..307f7ce4c 100644 | |
--- a/src/openssl.cr | |
+++ b/src/openssl.cr | |
@@ -96,6 +96,7 @@ module OpenSSL | |
class Error < OpenSSL::Error | |
getter error : ErrorType | |
+ getter? underlying_eof : Bool = false | |
def initialize(ssl : LibSSL::SSL, return_code : LibSSL::Int, func = nil) | |
@error = LibSSL.ssl_get_error(ssl, return_code) | |
@@ -109,6 +110,7 @@ module OpenSSL | |
case return_code | |
when 0 | |
message = "Unexpected EOF" | |
+ @underlying_eof = true | |
when -1 | |
cause = Errno.new(func || "OpenSSL") | |
message = "I/O error" | |
diff --git a/src/openssl/ssl/socket.cr b/src/openssl/ssl/socket.cr | |
index f3557f2a3..3ab50a8db 100644 | |
--- a/src/openssl/ssl/socket.cr | |
+++ b/src/openssl/ssl/socket.cr | |
@@ -115,7 +115,13 @@ abstract class OpenSSL::SSL::Socket < IO | |
LibSSL.ssl_read(@ssl, slice.to_unsafe, count).tap do |bytes| | |
if bytes <= 0 && !LibSSL.ssl_get_error(@ssl, bytes).zero_return? | |
- raise OpenSSL::SSL::Error.new(@ssl, bytes, "SSL_read") | |
+ ex = OpenSSL::SSL::Error.new(@ssl, bytes, "SSL_read") | |
+ if ex.underlying_eof? | |
+ # underlying BIO termianted gracefully, without terminating SSL aspect gracefully first | |
+ # some misbehaving servers "do this" so treat as EOF even though it's a protocol error | |
+ return 0 | |
+ end | |
+ raise ex | |
end | |
end | |
end | |
@@ -155,7 +161,10 @@ abstract class OpenSSL::SSL::Socket < IO | |
begin | |
ret = LibSSL.ssl_shutdown(@ssl) | |
break if ret == 1 # done bidirectional | |
- break if ret == 0 && sync_close? # done unidirectional, "this first successful call to SSL_shutdown() is sufficient" | |
+ if ret == 0 && sync_close? # done unidirectional, "this first successful call to SSL_shutdown() is sufficient" | |
+ #unbuffered_read(Bytes.new(0)) | |
+ break | |
+ end | |
raise OpenSSL::SSL::Error.new(@ssl, ret, "SSL_shutdown") if ret < 0 | |
rescue e : OpenSSL::SSL::Error | |
case e.error |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Dear gentlemen of evolvingweb.ca I am new to Drupal and even more so in Acquia Dev Desktop, I made all steps written on your website (https://evolvingweb.ca/blog/installing-drupal-console-windows) for the installation of Drupal Console, the problem I have is that it did not install all the dependencies that Drupal has. To verify that not all dependencies were installed, run "$ drupal" and display only the following commands:
C:\Users\HP\Sites\devdesktop\drupal878>drupal
Drupal Console version 1.9.4
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-e, --env[=ENV] The Environment name [default: "prod"]
--root[=ROOT] Define the Drupal root to be used in command execution
--debug Switches on debug mode
--learning Generate a verbose code output
-c, --generate-chain Shows command options and arguments as yaml output to be used in chain command
-i, --generate-inline Shows command options and arguments as inline command
-d, --generate-doc Shows command options and arguments as markdown
-t, --target[=TARGET] Site name you want to interact with (for local or remote sites)
-l, --uri=URI URI of the Drupal site to use (for multi-site environments or when running on an alternate port)
-y, --yes Skip confirmation and proceed
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
about Displays basic information about Drupal Console project
chain Chain command execution
check System requirement checker
exec Execute an external command.
help Displays help for a command
init Copy configuration files.
list Lists all available commands
server (serve,rs) Runs PHP built-in web server
database
database:add (dba) Add a database to settings.php
database:client (dbc) Launch a DB client if it's available
database:connect (dbco,sqlc) Shows DB connection
database:query (dbq,sqlq) Executes a SQL statement directly as argument
database:restore (dbr) Restore structure and contents of a database.
debug
debug:chain (dch) List available chain files.
debug:dotenv Debug Dotenv debug values.
debug:settings (dse) List user Drupal Console settings.
debug:site (dsi) List all known local and remote sites.
debug:update:composer (duc) Displays current updates available from the composer file
develop
develop:contribute Download Drupal + Drupal Console to contribute.
docker
docker:init Create a docker-compose.yml file
dotenv
dotenv:init Add support and required config to work with an .env file
generate
generate:site:alias (gsa) Generates a site alias.
quick
quick:start Download, install and serve a new Drupal project
settings
settings:set Change a specific setting value in DrupalConsole config file
site
site:install (si) Install a Drupal project
site:new Download a new Drupal project
Please I need your help, thanks in advance.
Sincerely Bladimir