gen-smtp / gen_smtp

The extensible Erlang SMTP client and server library.
Other
684 stars 265 forks source link

"Not a bitstring" error when running with STARTTLS in Elixir #297

Closed taobojlen closed 2 years ago

taobojlen commented 2 years ago

I'm using gen_smtp as an SMTP server in my Elixir app. I've set it up with STARTTLS, which seems to work (in my implementation of the gen_smtp_server_session behaviour, handle_STARTTLS runs as expected).

However, right after hitting handle_STARTTLS, the server throws an error:

[debug] Starting SMTP server on port 2525
[watch] build finished, watching for changes...
[debug] got a EHLO request with parameters nervous-energy

[debug] got a STARTTLS request

[debug] extensions [
  {'SIZE', '10485760'},
  {'8BITMIME', true},
  {'PIPELINING', true},
  {'STARTTLS', true}
]

[debug] SSL negotiation sucessful

[info] STARTTLS started (handle_STARTTLS)
[error] GenServer #PID<0.652.0> terminating
** (ArgumentError) errors were found at the given arguments:

  * 1st argument: not a bitstring

    :erlang.byte_size('EHLO nervous-energy\r\n')
    (gen_smtp 1.1.1) /home/tao/dev/my_app/deps/gen_smtp/src/binstr.erl:189: :binstr.strip/3
    (gen_smtp 1.1.1) /home/tao/dev/my_app/deps/gen_smtp/src/gen_smtp_server_session.erl:331: :gen_smtp_server_session.parse_request/1
    (gen_smtp 1.1.1) /home/tao/dev/my_app/deps/gen_smtp/src/gen_smtp_server_session.erl:265: :gen_smtp_server_session.handle_info/2
    (stdlib 3.16.1) gen_server.erl:695: :gen_server.try_dispatch/4
    (stdlib 3.16.1) gen_server.erl:771: :gen_server.handle_msg/6
    (stdlib 3.16.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Last message: {:ssl, {:sslsocket, {:gen_tcp, #Port<0.24>, :tls_connection, [session_id_tracker: #PID<0.653.0>]}, [#PID<0.655.0>, #PID<0.654.0>]}, 'EHLO nervous-energy\r\n'}
State: {:state, {:sslsocket, {:gen_tcp, #Port<0.24>, :tls_connection, [session_id_tracker: #PID<0.653.0>]}, [#PID<0.655.0>, #PID<0.654.0>]}, MyApp.Email.SmtpServer, :ranch_ssl, :gen_smtp_server, :undefined, [{'SIZE', '10485760'}, {'8BITMIME', true}, {'PIPELINING', true}, {'STARTTLS', true}], 10485760, false, :undefined, false, true, [], [hostname: 'nervous-energy', hostname: "app.myapp.email", certfile: "server.pem", keyfile: "server.key"]}
[error] Ranch listener :gen_smtp_server had connection process started with :gen_smtp_server_session:start_link/4 at #PID<0.652.0> exit with reason: {:badarg, [{:erlang, :byte_size, ['EHLO nervous-energy\r\n'], [error_info: %{module: :erl_erts_errors}]}, {:binstr, :strip, 3, [file: '/home/tao/dev/my_app/deps/gen_smtp/src/binstr.erl', line: 189]}, {:gen_smtp_server_session, :parse_request, 1, [file: '/home/tao/dev/my_app/deps/gen_smtp/src/gen_smtp_server_session.erl', line: 331]}, {:gen_smtp_server_session, :handle_info, 2, [file: '/home/tao/dev/my_app/deps/gen_smtp/src/gen_smtp_server_session.erl', line: 265]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 695]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 771]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}

All my handle_STARTTLS function does it write a log line and return the state:

  def handle_STARTTLS(state) do
   # state = [] at this point
    Logger.info("STARTTLS started (handle_STARTTLS)")
    state
  end

Do I need to do anything when running gen_smtp in Elixir to make this work?

For reference, here's the output from swaks when the error is thrown:

=== Trying 127.0.0.1:2525...
=== Connected to 127.0.0.1.
<-  220 nervous-energy SMTP gen_smtp server
 -> EHLO nervous-energy
<-  250-nervous-energy
<-  250-SIZE 10485760
<-  250-8BITMIME
<-  250-PIPELINING
<-  250 STARTTLS
 -> STARTTLS
<-  220 OK
=== TLS started with cipher TLSv1.3:TLS_AES_256_GCM_SHA384:256
=== TLS no local certificate set
=== TLS peer DN="/L=Default City/O=Default Company Ltd"
 ~> EHLO nervous-energy
*** Remote host closed connection unexpectedly.
seriyps commented 2 years ago

What is your OTP and gen_smtp versions?

seriyps commented 2 years ago

It might be https://github.com/gen-smtp/gen_smtp/pull/273#discussion_r712808588 which is fixed in the current master, but not in the last tagged version / not on hex.pm

taobojlen commented 2 years ago

This is on OTP 24. You're right -- I tried with the latest commit on master and it works! Thank you :)

seriyps commented 2 years ago

@arjan @mworrell would be cool to have a new release tagged soon. Seems latest gen_smtp release does not work well as a server on OTP-24. Not sure if we need to wait for "hut -> otp logger" PR first. Maybe it's less important?

mworrell commented 2 years ago

Just release now, we can add another release for the hut-changes.

@arjan can you make a release?