Kitura / Swift-SMTP

Swift SMTP client

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Way to define either TLS or SSL

dmitrykurochka opened this issue · comments

Hi! I tried to find in documentation a way to use ssl or tls option for sending mails. Is there any way except to define 465 or 587 port? Because I want have an options to define a port and tls separately. Does anyone have any suggestions?

I've asked because I could not send to gmail smtp by 465 port
only through 587

You can specify the port to use when you initialize your SMTP instance.
You can also specify what type of SSL to use. You can leave this parameter out and it will fallback to using SSL with no backing certificates. If your SMTP server requires SSL, Swift-SMTP will automatically attempt SSL (gmail requires SSL).
Can you show how you are configuring your SMTP instance? I have tested on gmail and default configurations should work.

Currently, I believe TLS happens IFF your server does not offer SSL.

I could add the ability to explicitly specify TLS, and throw any errors that occur (ie server requires SSL).

Could you try 465 port?
It would be great to have an option to explicitly specify tls, ssl option

Also an FYI, the Port type is merely a typealias for Int32. The SSL and TLS Ports are just enum cases with values 465 and 587 respectively. Perhaps this is poor design. But either way, you can safely specify which port to use, without affecting whether SSL or TLS is used. The latter is currently determined by the specifications of your SMTP server.

Ok, I'll test that again and let you know.
I'll go ahead and work on a PR to add the option to explicitly specify TLS/SSL. This has been requested before.

Cool, thanks a lot

I initialized my SMTP struct like this:

let smtp = SMTP(hostname: "smtp.gmail.com", email: "myemail", password: "mypassword")

I was able to send an email with this.

If you initialized like this:

let smtp = SMTP(hostname: "smtp.gmail.com", email: "myemail", password: "mypassword", port: 465)

it will error. I think this is because you can't initially attempt to connect to an SMTP server on a SSL port. You must first connect via it's TLS port (usually 587), and then upgrade to its SSL port (usually 465). So have you tried connecting to gmail without specifying a port? This makes it default to 587, which works.

I am going to add the ability to specify your server's TLS and SSL port, since this may change server to server.

That’s exactly what I’m talking about. That’s why we should have more configurable init function. Because I know thar default case works for gmail. But what about other providers. It should be configurable to be flexible.

3.0.0 has been released. Please give it a try and let me know of any issues.

Hi! I have tried new version.
Now 465 port is working ok,
but I could not get worked 587 port either by useTLS: true or useTLS: false

(Error code: -9805(0x-264D), ERROR: SSLHandshake, code: -9805, reason: errSSLClosedGraceful

Do you have any ideas why?

  • If you set port to 587 and set useTLS to true, it will fail because gmail's TLS port is 465.
  • If you set port to 587 and set useTLS to false, it will fail because gmail requires a TLS connection to send mails.

Is there a reason you are trying to use port 587?

I used nodemailer in another project. And it could send both to 465 with and without tls
And it sends to 587 only with tls enabled otherwise if fails
https://nodemailer.com/smtp/

That's what I found:

Ports 465 and 587 are intended for email client to email server communication - sending email.

Port 465 is for smtps
SSL encryption is started automatically before any SMTP level communication.

Port 587 is for msa
It is almost like standard SMTP port. MSA should accept email after authentication (e.g. after SMTP AUTH). It helps to stop outgoing spam when netmasters of DUL ranges can block outgoing connections to SMTP port (port 25).
SSL encryption may be started by STARTTLS command at SMTP level if server supports it and your ISP does not filter server's EHLO reply (reported 2014).

I'm not sure how that is happening in nodemailer. According to their docs:

port – is the port to connect to (defaults to 587 is secure is false or 465 if true)

secure – if true the connection will use TLS when connecting to server. If false (the default) then TLS is used if server supports the STARTTLS extension. In most cases set this value to true if you are connecting to port 465. For port 587 or 25 keep it false

Which is very similar to what Swift-SMTP does.

Are you explicitly setting the port to 465 and turning off secure (and why)? Perhaps in the background, when secure is set to false, it falls back to port 587 for the initial connection, but I don't know.

And it sends to 587 only with tls enabled otherwise if fails

This seems converse to their documentation. Their documentation states for most cases, if you're using port 587, set secure to false, which implies this is a working combination. I don't know why you would use port 587 and set secure to true, and why only that combination works.

Perhaps we've gotten some of our terminology mixed up? It's not quite clear to me yet the behavior you are looking for.

Also, if you've found a working combination for your server (gmail/port 465/useTLS = true), what else is in your requirements? The latest release with the changes you proposed I think make sense, it gives the user control over what port/TLS setting to use. These will vary from SMTP server to server, so it is up to the user to find these values for their server and plug them in.

Looking at nodemailer, one feature I think is worth adding is:

requireTLS – if this is true and secure is false then Nodemailer tries to use STARTTLS even if the server does not advertise support for it. If the connection can not be encrypted then message is not sent

Though I don't think this relates to your issue.

Note:

ignoreTLS – if this is true and secure is false then TLS is not used even if the server supports STARTTLS extension

is already implemented in Swift-SMTP. Do this by setting useTLS to false.

I do not trying to reimplement the same functionality as nodemailer. And I wondering why it works and Swift-SMTP doesn't. I just want be sure that I'll be prepared to any intergations with user's smtp. Because it should be fully configurable by user through web interface.

Also as you remember. In previous version of library I wasn't able to send through 465 port
only through 587
Not it's vice versa

I'm not sure how it's working in nodemailer. I hope to one day learn!

Also as you remember. In previous version of library I wasn't able to send through 465 port
only through 587
Not it's vice versa

Correct. In the previous version, this is what happened:

  • You set port to 587 (which was the default)
  • it opened a connection to your server on that port
  • It sends a ehlo/helo
  • If your server responses includes STARTTLS (gmail does), then it automatically closes the connection, creates a new TLS configured socket, and connects to the hard coded 465 port
  • This worked, but as you said, was quite rigid

With 3.0.0, things are different. You specify port and isSecure.

  • If isSecure = true, it automatically creates a TLS configured socket and connects to your specified port
  • If isSecure = false, it creates a normal socket and connects to your specified port, ignoring any STARTTLS response your server provides
  • I think this is an improvement, as it should provide all the flexibility required

I got it. Yeah I hope so. Thanks a lot for your work.