TCP Client Gmail IMAP 993

470 views
Skip to first unread message

Joran Greef

unread,
Feb 22, 2010, 5:41:19 PM2/22/10
to nodejs
I am writing an IMAP client for Gmail to connect using Node's TCP
client to imap.gmail.com on port 993 using TLS (with GNUTLS installed
correctly and picked up by Node).

I can connect and then authenticate with Gmail but sending further
commands does not cause any "data" events to be fired. Using openssl
works fine however.

This is the code I'm using:

var port = 993;
var host = 'imap.gmail.com';
var connection = Tcp.createConnection(port, host);
var caPem = '-----BEGIN CERTIFICATE-----\
MIIDXDCCAsWgAwIBAgIJAKL0UG+mRkSPMA0GCSqGSIb3DQEBBQUAMH0xCzAJBgNV\
BAYTAlVLMRQwEgYDVQQIEwtBY2tuYWNrIEx0ZDETMBEGA1UEBxMKUmh5cyBKb25l\
czEQMA4GA1UEChMHbm9kZS5qczEdMBsGA1UECxMUVGVzdCBUTFMgQ2VydGlmaWNh\
dGUxEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0wOTExMTEwOTUyMjJaFw0yOTExMDYw\
OTUyMjJaMH0xCzAJBgNVBAYTAlVLMRQwEgYDVQQIEwtBY2tuYWNrIEx0ZDETMBEG\
A1UEBxMKUmh5cyBKb25lczEQMA4GA1UEChMHbm9kZS5qczEdMBsGA1UECxMUVGVz\
dCBUTFMgQ2VydGlmaWNhdGUxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG\
9w0BAQEFAAOBjQAwgYkCgYEA8d8Hc6atq78Jt1HLp9agA/wpQfsFvkYUdZ1YsdvO\
kL2janjwHQgMMCy/Njal3FUEW0OLPebKZUJ8L44JBXSlVxU4zyiiSOWld8EkTetR\
AVT3WKQq3ud+cnxv7g8rGRQp1UHZwmdbZ1wEfAYq8QjYx6m1ciMgRo7DaDQhD29k\
d+UCAwEAAaOB4zCB4DAdBgNVHQ4EFgQUL9miTJn+HKNuTmx/oMWlZP9cd4QwgbAG\
A1UdIwSBqDCBpYAUL9miTJn+HKNuTmx/oMWlZP9cd4ShgYGkfzB9MQswCQYDVQQG\
EwJVSzEUMBIGA1UECBMLQWNrbmFjayBMdGQxEzARBgNVBAcTClJoeXMgSm9uZXMx\
EDAOBgNVBAoTB25vZGUuanMxHTAbBgNVBAsTFFRlc3QgVExTIENlcnRpZmljYXRl\
MRIwEAYDVQQDEwlsb2NhbGhvc3SCCQCi9FBvpkZEjzAMBgNVHRMEBTADAQH/MA0G\
CSqGSIb3DQEBBQUAA4GBADRXXA2xSUK5W1i3oLYWW6NEDVWkTQ9RveplyeS9MOkP\
e7yPcpz0+O0ZDDrxR9chAiZ7fmdBBX1Tr+pIuCrG/Ud49SBqeS5aMJGVwiSd7o1n\
dhU2Sz3Q60DwJEL1VenQHiVYlWWtqXBThe9ggqRPnCfsCRTP8qifKkjk45zWPcpN\
-----END CERTIFICATE-----';
connection.setEncoding('utf8');
connection.setNoDelay(true);
connection.setTimeout(0);
connection.setSecure("x509_PEM", caPem, 0, 0, 0);
connection.addListener('connect',
function() {
Log('Connected');
}
);
connection.addListener('data', function(data) { Log('Received: ' +
data); });
connection.addListener('end',
function() {
connection.close();
}
);
connection.addListener('close',
function() {
Log('Closed');
}
);

Could this have something to do with stdin/stderr?

Assistance would be greatly appreciated.

Joran Greef

unread,
Feb 23, 2010, 12:36:37 AM2/23/10
to nodejs
The same code works fine for pop.gmail.com: commands can be sent and
data received. Also, to be clear, for imap.gmail.com, the login
command can be sent and data is received for that but nothing else.
The same commands work fine with the openssl client.

Micheil Smith

unread,
Feb 23, 2010, 3:34:46 AM2/23/10
to nod...@googlegroups.com
Hi

It's an issue with security, I've got some documentation on it in
the docs/ directory of my SMTP module. GMail requires TLS/STARTTLS,
and node client's can't yet do that.

Also it'd be wise to not just write a library to interface with gmail's IMAP, but
rather an IMAP protocol interface.

- Micheil

> --
> You received this message because you are subscribed to the Google Groups "nodejs" group.
> To post to this group, send email to nod...@googlegroups.com.
> To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/nodejs?hl=en.
>

Joran Greef

unread,
Feb 23, 2010, 11:03:40 AM2/23/10
to nodejs
Thanks Micheil for the link to your docs. As suggested in your docs, I
tried openssl with "-starttls imap" but encountered the same problem:
the connection is established but commands do not receive a response.
Yet a previous openssl session had worked. Then I added the "-crlf"
option and that worked. Removing the "-starttls imap" also worked. The
problem was to do with terminating commands with "\n" instead of "\r
\n".

So it would appear to be good news: you can in fact use Node to
connect to an IMAP account over TLS. Use the setSecure method as above
(make sure that gnutls is installed before building Node) and end your
commands with "\r\n". With openssl, be sure to specify the "-crlf"
option as openssl won't do this by default.

Micheil Smith

unread,
Feb 23, 2010, 3:26:13 PM2/23/10
to nod...@googlegroups.com
It's news to me if the tcp client has gotten true secure connections.

- Micheil.

Joran Greef

unread,
Feb 27, 2010, 5:42:11 AM2/27/10
to nodejs
STARTTLS enables you to connect and then upgrade the connection to a
secure connection, whereas using setSecure as above would establish a
secure connection from the beginning.

It seems that STARTTLS is not in fact required by Gmail so long as you
establish a secure connection from the beginning. My Imap client is
now connecting to Gmail, listing, selecting, searching, fetching etc.
Also managed to get hold of Curl's CA bundle so that verifyPeer now
returns 1: http://curl.haxx.se/ca/cacert.pem

Reply all
Reply to author
Forward
0 new messages