What should I send after STARTLS? - c++

I am using smtp.gmail.com and port 587. After a successful connection, I send EHLO and receive the following:
250-smtp.gmail.com at your service, [62.16.4.123]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF
I choose STARTTLS and after that, I don't know what to send to the server and to login and send email.
If I will send something like AUTH LOGIN or base64-encrypted login with password, the connection is broken.
Can someone explain what my client should send to successfully finish the STARTTLS negotiation?
Or, should I start over with a new SSL connection?

After you send an (unencrypted) STARTTLS command, if the server returns any reply other than 220, handle it has a failure and move on with other SMTP commands as needed (though, at this point, the only one that really makes sense is QUIT).
If the server returns 220 to STARTTLS, you then need to perform the actual TLS handshake over the existing TCP connection, starting with a TLS CLIENT HELLO. Whatever TLS library you are using with your socket should be able to handle this for you, do not implement this from scratch.
If the TLS handshake is successful, then you can send further SMTP commands (through the TLS-encrypted channel), starting with a new EHLO (as the server's capabilities may and likely will change, most notably the available AUTH schemes), then followed by AUTH, MAIL FROM, RCPT TO, DATA/BDAT, etc and finally QUIT, as needed.
If the TLS handshake fails, the TCP connection is left in an unknown state, so further SMTP communication is not possible. All you can do at that point is close the TCP connection and start over.

Related

Connection timed out while sending email from Roundcube Webmail v1.4.11 ( iRedMail )

I am trying to setup a email server on Google clou for which I have used iRedMail. I have followed this link to setup. There was no error in logs while sending email to this email server but when I try to send from the UI to my email ID it is giving me following error in logs. ( /var/log/mail.log ).
Dec 8 10:19:36 comm postfix/smtp[4142]: connect to mail.tinydef.com[157.230.67.25]:25: Connection timed out
Dec 8 10:19:36 comm postfix/smtp[4142]: 4J8CnP4ND5z3ygl: to=<jamir46881#tinydef.com>, relay=none, delay=31, delays=0.02/0.03/31/0, dsn=4.4.1, status=deferred (connect to mail.tinydef.com[157.230.67.25]:25: Connection timed out)
I am aware that port 25 is blocked on GCP. Just trying to figure a way out from this situation. Is there any configuration that can be tweaked to change port 25 to some other port ?
You cannot send mail to external IP addresses on port 25 from instances in Google Cloud. There is no appeal process to change this policy.
Sending email from an instance
To function as a mail server requires communication between servers on port 25. Mail relays can use any port the mail server supports except for port 25.
iRedMail can function as a traditional mail server, which requires port 25, and as a mail relay to forward mail to a mail server.
Setup relayhost
Your solution is to configure iRedMail as a relay host forwarding mail on port 465 or 587 to a mail service such as Gmail, Office 365, SendGrid, etc. The email service will deliver your email.

OpenSSL: HTTPS proxy

So far, my proxy only deals HTTP connections on port 80: I'd like to improve it and make it manage HTTPS requests. Here's how it works:
the proxy is listening on a given port; Chrome can "see" the proxy thanks to SwitchyOmega plugin and connect the traffic on that given port.
The proxy reads the packet's header, gets the request (I parse only GET requests until now), e.g. GET http://www.google.it HTTP/1.1, gets the hostname parsing www.google.it, finds the IP address by resolving the hostname with gethostbyname and assumes the server port is number 80.
Now the proxy send to the server what it received from client by opening a socket: this socket is opened, binded, and then connected to the IP address I resolved before from the hostname.
I read here how to turn a socket into an SSL socket: after socket, bind, listen and accept syscalls, set what you need and pass the socket's file descriptor to SSL_set_fd so I can read and write data through the new SSL file descriptor.
What (most above all) bothers me is the creation of SSL context: if SSLv23_server_method is for servers and SSLv23_client_method is for clients, what should I use for my proxy?
I found no particular proxies configuration in OpenSSL documentation.
Thanks in advance for your help.
Edit: more detailed info about how the proxy works.
SSL/TLS has no concept of proxies, only point-to-point connections. Your proxy has a connection to the client, and a separate connection to the target server, and it is simply passing data between the two connections as needed. So the proxy has to secure (or not) those connections independently of each other, and how it must do that depends on how the client is asking the proxy to relay HTTP.
If the client sends a GET/POST/etc request to your proxy requesting an absolute HTTP URL, your proxy needs to connect to the target server without using SSL/TLS, and then relay the client's HTTP request and server's response back and forth. The client may or may not connect to your proxy using SSL/TLS. If it does, that session is only between the client and your proxy, and the data read from, and sent to, the client is encrypted/decrypted accordingly.
If the client sends a GET/POST/etc request to your proxy requesting an absolute HTTPS URL, your proxy needs to connect to the target server and establish its own SSL/TLS session with the server, and then relay the client's HTTP request and server's response back and forth. The proxy is acting as a client to the server, so use a client-based method (sslv23_client_method(), etc). The real client may or may not connect to your proxy using SSL/TLS. If it does, that session is only between the client and your proxy, and the data read from, and sent to, the client is encrypted/decrypted accordingly, separate from the encryption used on the server connection.
If the client sends a CONNECT request to your proxy, the proxy needs to connect to the requested host/port and then pass raw data back and forth as-is. No SSL/TLS is involved on the proxy's part. If the proxy handled the client's or server's SSL/TLS data, it would be acting as a MITM attacker, something SSL/TLS is designed to prevent. If the connection to the server is successful, the client and server (not the proxy) would secure their respective endpoints with SSL/TLS so they are talking to each other directly (needed for exchanging certificates and keys, and validating identities). The SSL/TLS handshake, and subsequent encrypted HTTP request/response data, would pass through the proxy as-is. The proxy would only be able to see the raw encrypted data, not the HTTP data, since only the client and server have the keys needed to decrypt the data.

What data must be sent after sending a STARTTLS command to an email server

I am writing an email client in C++ using the Winsock2 API to send emails via SMTP from a Gmail account. I am not using any other third party libraries.
I have connected to the Gmail server on port 587 (for TLS) and sent the basic EHLO and STARTTLS commands, but my question is this, what data should I specifically send after I have sent the STARTTLS command?
This is the server output for clarity:
Obviously the TLS handshake goes after the STARTTLS command, but what is the first and subsequent pieces of data that must be sent during the TLS handshake? From what I've read it should be binary data exchanging security certificates etc but I could not find specifically what data should be sent first.
I have searched numerous similar questions to this but I haven't found an answer that has said the specific data that must be sent after STARTTLS. I am aware of the existence of OpenSSL and I am not going to accept any answers telling my to install it instead.
The semantics and processing rules of the SMTP STARTTLS command are documented in RFC 3207.
After you have received a successful 220 response to the STARTTLS command, you must then begin a TLS handshake to establish encryption with which to encrypt/decrypt subsequent SMTP commands/responses. Upon completion of the handshake, the SMTP state is reset, so you must issue a new (now encrypted) EHLO command, and then proceed with your remaining (encrypted) SMTP commands as needed.
MSDN documents a high-level overview of the Transport Layer Security Protocol, with step-by-step instructions for the TLS Handshake Protocol. The specific details of each step are documented in Section 7 of RFC 2246 (TLS 1.0), RFC 4346 (TLS 1.1), and RFC 5246 (TLS 1.2).
So, unless you are planning on implementing TLS from scratch (please don't !!), you need to use a third-party library, such as OpenSSL, or you can use Microsoft's Secure Channel API, to handle the TLS handshake and subsequent encryption for you.

How can I keep an SSL handshake from timing out?

I have a browser that's sending requests through a very slow connection to a python web-proxy. The slowness isn't an issue with normal HTTP GET and POST requests, but when I try to open an HTTPS site it's failing. The proxy is getting the CONNECT request from the client and opening the connection with the server, but if the handshake doesn't finish in 30 seconds, the server is ending it.
Is there any way I can modify the proxy to keep the handshake open long enough for the client to finish it? Maybe some sort of SSL handshake keep-alive?

Gmail sends EHLO..QUIT immediately to custom SMTP/MTA server

I'm trying to write a simple receiving mail server (MTA) in C++ on Linux, I've gotten as far as when I try to send mail to it from my Gmail account, a Google server connects, but then quits right after. I have no idea what I'm missing. The current communication looks like:
S: 220 mx.domain.com ESMTP<CR><LF>
C: EHLO mail.google.com<CR><LF>QUIT<CR><LF>
S: 250 mx.domain.com at your service<CR><LF>221 Bye<CR><LF>
I'm very confused by the fact the Google mail server is sending both EHLO and QUIT in the same request. And of course it never sends the actual mail. Any ideas as to why it quits?
In my case it was because the server sent the response to the client padded with '\0' after capping to the correct response length everything works as intended.