--- a/loudmouth/lm-connection.c Sun Feb 24 01:01:24 2008 +0100
+++ b/loudmouth/lm-connection.c Mon Feb 25 20:37:24 2008 +0100
@@ -79,7 +79,7 @@
GSList *handlers[LM_MESSAGE_TYPE_UNKNOWN];
/* XMPP1.0 stuff (SASL, resource binding, StartTLS) */
- gboolean use_xmpp;
+ gboolean use_sasl;
LmSASL *sasl;
gchar *resource;
LmMessageHandler *features_cb;
@@ -455,11 +455,7 @@
}
if (!connection_get_server_from_jid (connection->jid, &domain)) {
- g_set_error (error,
- LM_ERROR,
- LM_ERROR_CONNECTION_FAILED,
- "You need to either set server hostname or jid");
- return FALSE;
+ domain = g_strdup (connection->server);
}
lm_message_queue_attach (connection->queue, connection->context);
@@ -737,7 +733,7 @@
lm_verbose ("XMPP 1.0 stream received: %s\n",
connection->stream_id);
- connection->use_xmpp = TRUE;
+ connection->use_sasl = TRUE;
/* stream is started multiple times, but we only want
* one sasl mechanism */
@@ -787,7 +783,7 @@
static void
connection_stream_error (LmConnection *connection, LmMessage *m)
{
- LmMessageNode *node;
+ LmMessageNode *node, *reason_node;
LmDisconnectReason reason;
g_return_if_fail (connection != NULL);
@@ -796,16 +792,16 @@
node = m->node;
/* Resource conflict */
- node = lm_message_node_get_child (node, "conflict");
- if (node) {
+ reason_node = lm_message_node_get_child (node, "conflict");
+ if (reason_node) {
lm_verbose ("Stream error: Conflict (resource connected elsewhere)\n");
reason = LM_DISCONNECT_REASON_RESOURCE_CONFLICT;
return;
}
/* XML is crack */
- node = lm_message_node_get_child (node, "xml-not-well-formed");
- if (node) {
+ reason_node = lm_message_node_get_child (node, "xml-not-well-formed");
+ if (reason_node) {
lm_verbose ("Stream error: XML not well formed\n");
reason = LM_DISCONNECT_REASON_INVALID_XML;
return;
@@ -1039,6 +1035,7 @@
{
LmMessageNode *bind_node;
LmMessageNode *starttls_node;
+ LmMessageNode *old_auth;
starttls_node = lm_message_node_find_child (message->node, "starttls");
if (connection->ssl && lm_ssl_get_use_starttls (connection->ssl)) {
@@ -1107,6 +1104,33 @@
}
}
+ old_auth = lm_message_node_find_child (message->node, "auth");
+ if (connection->use_sasl && old_auth) {
+ g_debug ("Server uses XEP-0078 (jabber iq auth) instead of SASL");
+ /* So the server is XMPP1.0, but doesn't support SASL and uses
+ * obsolete XEP-0078 instead. Let's cope. */
+
+ connection->use_sasl = FALSE;
+
+ if (connection->sasl) {
+ const gchar *user, *pass;
+
+ lm_sasl_get_auth_params (connection->sasl, &user, &pass);
+ if (user && pass) {
+ GError *error = NULL;
+ _lm_connection_old_auth (connection, user, pass,
+ connection->resource, &error);
+
+ if (error)
+ g_error_free (error);
+
+ }
+
+ lm_sasl_free (connection->sasl);
+ connection->sasl = NULL;
+ }
+ }
+
return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
}
@@ -1152,7 +1176,7 @@
connection->keep_alive_source = NULL;
connection->keep_alive_rate = 0;
connection->socket = NULL;
- connection->use_xmpp = FALSE;
+ connection->use_sasl = FALSE;
connection->tls_started = FALSE;
connection->id_handlers = g_hash_table_new_full (g_str_hash,
@@ -1384,11 +1408,6 @@
GDestroyNotify notify,
GError **error)
{
- LmMessage *m;
- LmMessageHandler *handler;
- gboolean result;
- AuthReqData *data;
-
g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (username != NULL, FALSE);
g_return_val_if_fail (password != NULL, FALSE);
@@ -1412,7 +1431,7 @@
connection->effective_jid = g_strdup_printf ("%s/%s",
connection->jid, connection->resource);
- if (connection->use_xmpp) {
+ if (connection->use_sasl) {
lm_sasl_authenticate (connection->sasl,
username, password,
connection->server,
@@ -1429,6 +1448,20 @@
return TRUE;
}
+ return _lm_connection_old_auth (connection, username, password,
+ resource, error);
+}
+
+gboolean
+_lm_connection_old_auth (LmConnection *connection, const gchar *username,
+ const gchar *password, const gchar *resource, GError **error)
+{
+ LmMessage *m;
+ AuthReqData *data;
+ LmMessageHandler *handler;
+ gboolean result;
+
+
m = connection_create_auth_req_msg (username);
data = g_new0 (AuthReqData, 1);
--- a/loudmouth/lm-connection.h Sun Feb 24 01:01:24 2008 +0100
+++ b/loudmouth/lm-connection.h Mon Feb 25 20:37:24 2008 +0100
@@ -164,6 +164,11 @@
LmConnection* lm_connection_ref (LmConnection *connection);
void lm_connection_unref (LmConnection *connection);
+gboolean
+_lm_connection_old_auth (LmConnection *connection, const gchar *username,
+ const gchar *password, const gchar *resource,
+ GError **errror);
+
G_END_DECLS
--- a/loudmouth/lm-message.c Sun Feb 24 01:01:24 2008 +0100
+++ b/loudmouth/lm-message.c Mon Feb 25 20:37:24 2008 +0100
@@ -36,14 +36,15 @@
{ LM_MESSAGE_TYPE_IQ, "iq" },
{ LM_MESSAGE_TYPE_STREAM, "stream:stream" },
{ LM_MESSAGE_TYPE_STREAM_FEATURES, "stream:features" },
+ { LM_MESSAGE_TYPE_STREAM_ERROR, "stream:error" },
{ LM_MESSAGE_TYPE_AUTH, "auth" },
{ LM_MESSAGE_TYPE_CHALLENGE, "challenge" },
{ LM_MESSAGE_TYPE_RESPONSE, "response" },
{ LM_MESSAGE_TYPE_SUCCESS, "success" },
{ LM_MESSAGE_TYPE_FAILURE, "failure" },
- { LM_MESSAGE_TYPE_STREAM_ERROR, "stream:error" },
{ LM_MESSAGE_TYPE_PROCEED, "proceed" },
- { LM_MESSAGE_TYPE_STARTTLS, "starttls" }
+ { LM_MESSAGE_TYPE_STARTTLS, "starttls" },
+ { LM_MESSAGE_TYPE_UNKNOWN, NULL }
};
static struct SubTypeNames
@@ -83,10 +84,10 @@
}
for (i = LM_MESSAGE_TYPE_MESSAGE;
- i <= LM_MESSAGE_TYPE_STARTTLS;
+ i < LM_MESSAGE_TYPE_UNKNOWN;
++i) {
if (strcmp (type_str, type_names[i].name) == 0) {
- return i;
+ return type_names[i].type;
}
}
--- a/loudmouth/lm-message.h Sun Feb 24 01:01:24 2008 +0100
+++ b/loudmouth/lm-message.h Mon Feb 25 20:37:24 2008 +0100
@@ -42,13 +42,13 @@
LM_MESSAGE_TYPE_PRESENCE,
LM_MESSAGE_TYPE_IQ,
LM_MESSAGE_TYPE_STREAM,
+ LM_MESSAGE_TYPE_STREAM_ERROR,
LM_MESSAGE_TYPE_STREAM_FEATURES,
LM_MESSAGE_TYPE_AUTH,
LM_MESSAGE_TYPE_CHALLENGE,
LM_MESSAGE_TYPE_RESPONSE,
LM_MESSAGE_TYPE_SUCCESS,
LM_MESSAGE_TYPE_FAILURE,
- LM_MESSAGE_TYPE_STREAM_ERROR,
LM_MESSAGE_TYPE_PROCEED,
LM_MESSAGE_TYPE_STARTTLS,
LM_MESSAGE_TYPE_UNKNOWN
--- a/loudmouth/lm-sasl.c Sun Feb 24 01:01:24 2008 +0100
+++ b/loudmouth/lm-sasl.c Mon Feb 25 20:37:24 2008 +0100
@@ -834,3 +834,11 @@
}
+void
+lm_sasl_get_auth_params (LmSASL *sasl, const gchar **username,
+ const gchar **password)
+{
+ *username = sasl->username;
+ *password = sasl->password;
+}
+
--- a/loudmouth/lm-sasl.h Sun Feb 24 01:01:24 2008 +0100
+++ b/loudmouth/lm-sasl.h Mon Feb 25 20:37:24 2008 +0100
@@ -46,6 +46,10 @@
void lm_sasl_free (LmSASL *sasl);
+void
+lm_sasl_get_auth_params (LmSASL *sasl, const gchar **username,
+ const gchar **password);
+
G_END_DECLS
#endif /* __LM_SASL_H__ */
--- a/loudmouth/lm-socket.c Sun Feb 24 01:01:24 2008 +0100
+++ b/loudmouth/lm-socket.c Mon Feb 25 20:37:24 2008 +0100
@@ -496,10 +496,12 @@
g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
"Connection failed.\n");
- _lm_socket_failed_with_error (connect_data, err);
-
- socket->watch_connect = NULL;
- return FALSE;
+ /* error condition, but might be possible to recover
+ * from it (by connecting to the next host) */
+ if (!_lm_socket_failed_with_error (connect_data, err)) {
+ socket->watch_connect = NULL;
+ return FALSE;
+ }
}
}