On Thu, 2019-05-09 at 11:03 -0700, James Bottomley wrote:
> I can certainly test things out.
Hi,
that's great, thanks.
> To be honest, I've had problems with TLSv1.3 every time it's been
> negotiated, so disabling it is a reasonable thing to do.
I see. If you are still willing to help, then it'll be appreciated.
> I suppose there's no gntuls-cli equivalent for glib-networking? That
> would be the best way to test it.
I agree, but I'm not aware of anything like that (which doesn't mean it
doesn't exist). I made a little test program as promised, see the
attachment. The first line contains a comment with a command to compile
and run it (against Google's IMAP server). It's only a test program,
mimic-ing what Evolution (or better Camel library from evolution-data-
server) does. You may have installed development packages for glib and,
if split, also for glib's gio, to be able to compile it.
Bye,
Milan
P.S.: The result of the run as is in the file itself is below:
$ ./imap-conn imap.googlemail.com 993
Connected to imap.googlemail.com:993
Response: * OK Gimap ready for requests from {IPADDRESS} {SOMETOKEN}
Request: A01 CAPABILITY
Response: * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST
CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN
AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH
A01 OK Thats all she wrote! {SOMETOKEN}
Request: A02 LOGOUT
Response: * BYE Logout Requested {SOMETOKEN}
A02 OK Quoth the raven, nevermore... {SOMETOKEN}
/* gcc `pkg-config --cflags --libs glib-2.0 gio-2.0` imap-conn.c -g -O0 -o imap-conn && ./imap-conn imap.googlemail.com 993 */
#include <glib.h>
#include <gio/gio.h>
static gboolean
read_stream_data (GIOStream *stream)
{
GInputStream *input;
gchar buffer[2048 + 1];
gsize count;
GError *error = NULL;
input = g_io_stream_get_input_stream (stream);
count = g_input_stream_read (input, buffer, G_N_ELEMENTS (buffer) - 1, NULL, &error);
if (count == -1) {
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT)) {
g_clear_error (&error);
} else {
g_printerr ("Failed to read data from the server: %s\n", error ? error->message : "Unknown error");
g_clear_error (&error);
return FALSE;
}
} else {
buffer[count] = 0;
g_print ("Response: %s\n", buffer);
}
return TRUE;
}
static gboolean
issue_command (GIOStream *stream,
const gchar *command)
{
GOutputStream *output;
gsize count, written = 0;
GError *error = NULL;
output = g_io_stream_get_output_stream (stream);
count = strlen (command);
if (!g_output_stream_write_all (output, command, count, &written, NULL, &error)) {
g_printerr ("Failed to write command to the output stream: %s\n", error ? error->message : "Unknown error");
g_clear_error (&error);
return FALSE;
}
if (written != count) {
g_printerr ("Wrote only %d bytes, instead of %d\n", written, count);
return FALSE;
}
if (!g_output_stream_write_all (output, "\r\n", 2, &written, NULL, &error)) {
g_printerr ("Failed to write command end to the output stream: %s\n", error ? error->message : "Unknown error");
g_clear_error (&error);
return FALSE;
}
if (written != 2) {
g_printerr ("Wrote only %d bytes, instead of %d\n", written, 2);
return FALSE;
}
if (!g_output_stream_flush (output, NULL, &error)) {
g_printerr ("Failed to flush output stream\n", error ? error->message : "Unknown error");
g_clear_error (&error);
return FALSE;
}
g_print ("Request: %s\n", command);
return read_stream_data (stream);
}
static gint
run_connection (const gchar *host,
gushort port)
{
GSocketConnectable *connectable;
GSocketConnection *connection;
GSocketClient *client;
gint ret = 0;
GError *error = NULL;
connectable = g_object_new (G_TYPE_NETWORK_ADDRESS,
"scheme", "imap",
"hostname", host,
"port", port,
NULL);
client = g_socket_client_new ();
g_socket_client_set_timeout (client, 10);
g_socket_client_set_tls (client, TRUE);
connection = g_socket_client_connect (client, connectable, NULL, &error);
if (connection) {
GSocket *socket;
GIOStream *stream;
g_print ("Connected to %s:%d\n", host, port);
socket = g_socket_connection_get_socket (connection);
if (socket) {
g_socket_set_timeout (socket, 10);
g_socket_set_keepalive (socket, TRUE);
}
stream = G_IO_STREAM (connection);
if (!read_stream_data (stream))
ret = 3;
else if (!issue_command (stream, "A01 CAPABILITY"))
ret = 4;
else if (!issue_command (stream, "A02 LOGOUT"))
ret = 5;
if (!g_io_stream_close (stream, NULL, &error)) {
if (!ret)
ret = 6;
g_printerr ("Failed to close connection: %s\n", error ? error->message : "Unknown error");
g_clear_error (&error);
}
g_object_unref (connection);
} else {
g_printerr ("Failed to connect to %s:%d: %s\n", host, port, error ? error->message : "Unknown error");
g_clear_error (&error);
ret = 2;
}
g_object_unref (connectable);
g_object_unref (client);
}
gint
main (gint argc,
gchar *argv[])
{
const gchar *host;
gushort port;
if (argc != 3) {
g_printerr ("Requires two arguments, IMAP server host name and port, in this order\n");
return 1;
}
host = argv[1];
port = (gushort) g_ascii_strtoll (argv[2], NULL, 10);
return run_connection (host, port);
}
_______________________________________________
evolution-hackers mailing list
[email protected]
To change your list options or unsubscribe, visit ...
https://mail.gnome.org/mailman/listinfo/evolution-hackers