# HG changeset patch # User Dafydd Harries # Date 1193842140 0 # Node ID 2a467914cea50a49e452044cffffff9ca7f91081 # Parent f42625a65dd3a2fc08153c160e7cbebe33849b18# Parent 153357413e1b0ad767705b6765a5266fcfeb3407 Merge branch '1.3' of http://projects.collabora.co.uk/~ptlo/git/loudmouth into 1.3 diff -r f42625a65dd3 -r 2a467914cea5 examples/Makefile.am --- a/examples/Makefile.am Tue Oct 30 19:48:50 2007 +0000 +++ b/examples/Makefile.am Wed Oct 31 14:49:00 2007 +0000 @@ -6,7 +6,6 @@ test-lm \ test-http-proxy \ test-tunnel \ - lm-send-sync \ lm-send-async \ lm-change-password \ lm-register @@ -17,8 +16,6 @@ test_tunnel_SOURCES = test-tunnel.c -lm_send_sync_SOURCES = lm-send-sync.c - lm_send_async_SOURCES = lm-send-async.c lm_change_password_SOURCES = lm-change-password.c diff -r f42625a65dd3 -r 2a467914cea5 examples/lm-send-sync.c --- a/examples/lm-send-sync.c Tue Oct 30 19:48:50 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,216 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2004 Imendio AB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * Description: - * A little program that let you send jabber messages to another person. - * - * Build instructions: - * gcc -o lm-send-sync `pkg-config --cflags --libs loudmouth-1.0` lm-send-sync.c - */ - -#include -#include - -#include - -static gchar expected_fingerprint[20]; - -static gchar *server = NULL; -static gint port = 5222; -static gchar *username = NULL; -static gchar *password = NULL; -static gchar *resource = "lm-send-sync"; -static gchar *recipient = NULL; -static gchar *fingerprint = NULL; -static gchar *message = "test synchronous message"; - -static GOptionEntry entries[] = -{ - { "server", 's', 0, G_OPTION_ARG_STRING, &server, - "Server to connect to", NULL }, - { "port", 'P', 0, G_OPTION_ARG_INT, &port, - "Port to connect to [default=5222]", NULL }, - { "username", 'u', 0, G_OPTION_ARG_STRING, &username, - "Username to connect with (e.g. 'user' in user@server.org)", NULL }, - { "password", 'p', 0, G_OPTION_ARG_STRING, &password, - "Password to try", NULL }, - { "resource", 'r', 0, G_OPTION_ARG_STRING, &resource, - "Resource connect with [default=lm-send-sync]", NULL }, - { "recipient", 'R', 0, G_OPTION_ARG_STRING, &recipient, - "Recipient to send the message to (e.g. user@server.org)", NULL }, - { "fingerprint", 'f', 0, G_OPTION_ARG_STRING, &fingerprint, - "SSL Fingerprint to use", NULL }, - { "message", 'm', 0, G_OPTION_ARG_STRING, &message, - "Message to send to recipient [default=test synchronous message]", NULL }, - { NULL } -}; - -static gchar * -get_part_name (const gchar *username) -{ - const gchar *ch; - - g_return_val_if_fail (username != NULL, NULL); - - ch = strchr (username, '@'); - if (!ch) { - return NULL; - } - - return g_strndup (username, ch - username); -} - -static void -print_finger (const char *fpr, - unsigned int size) -{ - gint i; - for (i = 0; i < size-1; i++) { - g_printerr ("%02X:", fpr[i]); - } - - g_printerr ("%02X", fpr[size-1]); -} - -static LmSSLResponse -ssl_cb (LmSSL *ssl, - LmSSLStatus status, - gpointer ud) -{ - g_print ("LmSendSync: SSL status:%d\n", status); - - switch (status) { - case LM_SSL_STATUS_NO_CERT_FOUND: - g_printerr ("LmSendSync: No certificate found!\n"); - break; - case LM_SSL_STATUS_UNTRUSTED_CERT: - g_printerr ("LmSendSync: Certificate is not trusted!\n"); - break; - case LM_SSL_STATUS_CERT_EXPIRED: - g_printerr ("LmSendSync: Certificate has expired!\n"); - break; - case LM_SSL_STATUS_CERT_NOT_ACTIVATED: - g_printerr ("LmSendSync: Certificate has not been activated!\n"); - break; - case LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH: - g_printerr ("LmSendSync: Certificate hostname does not match expected hostname!\n"); - break; - case LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH: { - const char *fpr = lm_ssl_get_fingerprint (ssl); - g_printerr ("LmSendSync: Certificate fingerprint does not match expected fingerprint!\n"); - g_printerr ("LmSendSync: Remote fingerprint: "); - print_finger (fpr, 16); - - g_printerr ("\n" - "LmSendSync: Expected fingerprint: "); - print_finger (expected_fingerprint, 16); - g_printerr ("\n"); - break; - } - case LM_SSL_STATUS_GENERIC_ERROR: - g_printerr ("LmSendSync: Generic SSL error!\n"); - break; - } - - return LM_SSL_RESPONSE_CONTINUE; -} - -int -main (int argc, char **argv) -{ - GOptionContext *context; - GError *error = NULL; - LmConnection *connection; - LmMessage *m; - gchar *user; - - context = g_option_context_new ("- test send message synchronously"); - g_option_context_add_main_entries (context, entries, NULL); - g_option_context_parse (context, &argc, &argv, NULL); - g_option_context_free (context); - - if (!username || !password || !recipient) { - g_printerr ("For usage, try %s --help\n", argv[0]); - return EXIT_FAILURE; - } - - if (username && strchr (username, '@') == NULL) { - g_printerr ("LmSendSync: Username must have an '@' included\n"); - return EXIT_FAILURE; - } - - connection = lm_connection_new (server); - lm_connection_set_port (connection, port); - lm_connection_set_jid (connection, username); - - if (fingerprint) { - LmSSL *ssl; - char *p; - int i; - - if (port == LM_CONNECTION_DEFAULT_PORT) { - lm_connection_set_port (connection, - LM_CONNECTION_DEFAULT_PORT_SSL); - } - - for (i = 0, p = fingerprint; *p && *(p+1); i++, p += 3) { - expected_fingerprint[i] = (unsigned char) g_ascii_strtoull (p, NULL, 16); - } - - ssl = lm_ssl_new (expected_fingerprint, - (LmSSLFunction) ssl_cb, - NULL, NULL); - - lm_connection_set_ssl (connection, ssl); - lm_ssl_unref (ssl); - } - - if (!lm_connection_open_and_block (connection, &error)) { - g_printerr ("LmSendSync: Could not open a connection: %s\n", error->message); - return EXIT_FAILURE; - } - - user = get_part_name (username); - if (!lm_connection_authenticate_and_block (connection, - user, password, resource, - &error)) { - g_free (user); - g_printerr ("LmSendSync: Failed to authenticate: %s\n", error->message); - return EXIT_FAILURE; - } - g_free (user); - - m = lm_message_new (recipient, LM_MESSAGE_TYPE_MESSAGE); - lm_message_node_add_child (m->node, "body", message); - - if (!lm_connection_send (connection, m, &error)) { - g_printerr ("LmSendSync: Failed to send message: %s\n", error->message); - return EXIT_FAILURE; - } - - lm_message_unref (m); - - lm_connection_close (connection, NULL); - lm_connection_unref (connection); - - return EXIT_SUCCESS; -} - diff -r f42625a65dd3 -r 2a467914cea5 loudmouth/lm-connection.c --- a/loudmouth/lm-connection.c Tue Oct 30 19:48:50 2007 +0000 +++ b/loudmouth/lm-connection.c Wed Oct 31 14:49:00 2007 +0000 @@ -145,6 +145,8 @@ static void connection_stream_received (LmConnection *connection, LmMessage *m); +static void connection_stream_error (LmConnection *connection, + LmMessage *m); static gint connection_handler_compare_func (HandlerData *a, HandlerData *b); @@ -256,7 +258,7 @@ connection_stream_received (connection, m); goto out; } - + if ((lm_message_get_sub_type (m) == LM_MESSAGE_SUB_TYPE_ERROR) || (lm_message_get_sub_type (m) == LM_MESSAGE_SUB_TYPE_RESULT)) { id = lm_message_node_get_attribute (m->node, "id"); @@ -287,6 +289,11 @@ m); } + if (lm_message_get_type (m) == LM_MESSAGE_TYPE_STREAM_ERROR) { + connection_stream_error (connection, m); + goto out; + } + out: lm_connection_unref (connection); @@ -736,6 +743,41 @@ } } +static void +connection_stream_error (LmConnection *connection, LmMessage *m) +{ + LmMessageNode *node; + LmDisconnectReason reason; + + g_return_if_fail (connection != NULL); + g_return_if_fail (m != NULL); + + node = m->node; + + /* Resource conflict */ + node = lm_message_node_get_child (node, "conflict"); + if (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) { + lm_verbose ("Stream error: XML not well formed\n"); + reason = LM_DISCONNECT_REASON_INVALID_XML; + return; + } + + lm_verbose ("Stream error: Unrecognised error\n"); + reason = LM_DISCONNECT_REASON_ERROR; + connection->stream_id = g_strdup (lm_message_node_get_attribute (m->node, + "id"));; + connection_do_close (connection); + connection_signal_disconnect (connection, reason); +} + static gint connection_handler_compare_func (HandlerData *a, HandlerData *b) { @@ -921,6 +963,7 @@ /* use whatever server returns as our effective jid */ jid_node = lm_message_node_find_child (message->node, "jid"); if (jid_node) { + g_free (connection->effective_jid); connection->effective_jid = g_strdup (lm_message_node_get_value (jid_node)); } @@ -1339,14 +1382,16 @@ user_data, notify); + connection->resource = g_strdup (resource); + connection->effective_jid = g_strdup_printf ("%s/%s", + connection->jid, connection->resource); + if (connection->use_xmpp) { lm_sasl_authenticate (connection->sasl, username, password, connection->server, connection_sasl_auth_finished); - connection->resource = g_strdup (resource); - connection->features_cb = lm_message_handler_new (connection_features_cb, NULL, NULL); @@ -1588,22 +1633,20 @@ } /** - * lm_connection_get_effective_jid: + * lm_connection_get_full_jid: * @connection: an #LmConnection * - * Returns the jid that server set for us after resource binding. + * Returns the full jid that server set for us after + * resource binding, complete with the resource. * * Return value: the jid **/ -const gchar * -lm_connection_get_effective_jid (LmConnection *connection) +gchar * +lm_connection_get_full_jid (LmConnection *connection) { g_return_val_if_fail (connection != NULL, NULL); - if (connection->effective_jid) - return connection->effective_jid; - else - return connection->jid; + return connection->effective_jid; } /** @@ -2023,6 +2066,20 @@ } /** + * lm_connection_get_client_host: + * @connection: An #LmConnection + * + * Returns the local host name of the connection. + * + * Return value: A newly allocated string representing the local host name. + **/ +gchar * +lm_connection_get_local_host (LmConnection *connection) +{ + return lm_socket_get_local_host (connection->socket); +} + +/** * lm_connection_ref: * @connection: Connection to add a reference to. * diff -r f42625a65dd3 -r 2a467914cea5 loudmouth/lm-connection.h --- a/loudmouth/lm-connection.h Tue Oct 30 19:48:50 2007 +0000 +++ b/loudmouth/lm-connection.h Wed Oct 31 14:49:00 2007 +0000 @@ -56,6 +56,8 @@ LM_DISCONNECT_REASON_PING_TIME_OUT, LM_DISCONNECT_REASON_HUP, LM_DISCONNECT_REASON_ERROR, + LM_DISCONNECT_REASON_RESOURCE_CONFLICT, + LM_DISCONNECT_REASON_INVALID_XML, LM_DISCONNECT_REASON_UNKNOWN } LmDisconnectReason; @@ -116,7 +118,7 @@ void lm_connection_set_jid (LmConnection *connection, const gchar *jid); const gchar * lm_connection_get_jid (LmConnection *connection); -const gchar * lm_connection_get_effective_jid (LmConnection *connection); +gchar * lm_connection_get_full_jid (LmConnection *connection); guint lm_connection_get_port (LmConnection *connection); void lm_connection_set_port (LmConnection *connection, @@ -158,9 +160,11 @@ const gchar *str, GError **error); LmConnectionState lm_connection_get_state (LmConnection *connection); +gchar * lm_connection_get_local_host (LmConnection *connection); LmConnection* lm_connection_ref (LmConnection *connection); void lm_connection_unref (LmConnection *connection); + G_END_DECLS #endif /* __LM_CONNECTION_H__ */ diff -r f42625a65dd3 -r 2a467914cea5 loudmouth/lm-internals.h --- a/loudmouth/lm-internals.h Tue Oct 30 19:48:50 2007 +0000 +++ b/loudmouth/lm-internals.h Wed Oct 31 14:49:00 2007 +0000 @@ -108,6 +108,7 @@ socklen_t *len); const gchar * _lm_sock_get_error_str (int err); const gchar * _lm_sock_addrinfo_get_error_str (int err); +gchar * _lm_sock_get_local_host (LmSocketT sock); #ifdef USE_TCP_KEEPALIVES gboolean _lm_sock_set_keepalive (LmSocketT sock, int delay); diff -r f42625a65dd3 -r 2a467914cea5 loudmouth/lm-sock.c --- a/loudmouth/lm-sock.c Tue Oct 30 19:48:50 2007 +0000 +++ b/loudmouth/lm-sock.c Wed Oct 31 14:49:00 2007 +0000 @@ -32,6 +32,7 @@ #include #include #include +#include #define LM_SHUTDOWN SHUT_RDWR #else /* G_OS_WIN32 */ @@ -46,6 +47,8 @@ #include "lm-sock.h" #include "lm-debug.h" +#define IPV6_MAX_ADDRESS_LEN 46 /* 45 + '\0' */ + static gboolean initialised = FALSE; gboolean @@ -323,3 +326,37 @@ } #endif /* USE_TCP_KEEPALIVES */ +gchar * +_lm_sock_get_local_host (LmSocketT sock) +{ + struct sockaddr addr_info; + void *sock_addr; + socklen_t namelen; + char addrbuf[IPV6_MAX_ADDRESS_LEN]; + const char *host; + + namelen = sizeof (struct sockaddr); + if (getsockname (sock, &addr_info, &namelen)) { + return NULL; + } + + switch (addr_info.sa_family) { + case AF_INET: + + sock_addr = & (((struct sockaddr_in *) &addr_info)->sin_addr); + break; + case AF_INET6: + sock_addr = & (((struct sockaddr_in6 *) &addr_info)->sin6_addr); + break; + default: + return NULL; + } + /* inet_ntoa has been obsoleted in favour of inet_ntop */ + host = inet_ntop (addr_info.sa_family, + sock_addr, + addrbuf, + IPV6_MAX_ADDRESS_LEN); + + return g_strdup (host); +} + diff -r f42625a65dd3 -r 2a467914cea5 loudmouth/lm-socket.c --- a/loudmouth/lm-socket.c Tue Oct 30 19:48:50 2007 +0000 +++ b/loudmouth/lm-socket.c Wed Oct 31 14:49:00 2007 +0000 @@ -1096,6 +1096,12 @@ } } +gchar * +lm_socket_get_local_host (LmSocket *socket) +{ + return _lm_sock_get_local_host (socket->fd); +} + LmSocket * lm_socket_ref (LmSocket *socket) { diff -r f42625a65dd3 -r 2a467914cea5 loudmouth/lm-socket.h --- a/loudmouth/lm-socket.h Tue Oct 30 19:48:50 2007 +0000 +++ b/loudmouth/lm-socket.h Wed Oct 31 14:49:00 2007 +0000 @@ -71,6 +71,7 @@ #endif gboolean lm_socket_starttls (LmSocket *socket); gboolean lm_socket_set_keepalive (LmSocket *socket, int delay); +gchar * lm_socket_get_local_host (LmSocket *socket); #endif /* __LM_SOCKET_H__ */ diff -r f42625a65dd3 -r 2a467914cea5 loudmouth/lm-ssl-openssl.c --- a/loudmouth/lm-ssl-openssl.c Tue Oct 30 19:48:50 2007 +0000 +++ b/loudmouth/lm-ssl-openssl.c Wed Oct 31 14:49:00 2007 +0000 @@ -321,6 +321,13 @@ gint ssl_ret; GIOStatus status; + if (!ssl->ssl_ctx) { + g_set_error (error, + LM_ERROR, LM_ERROR_CONNECTION_OPEN, + "No SSL Context for OpenSSL"); + return FALSE; + } + ssl->ssl = SSL_new(ssl->ssl_ctx); if (ssl->ssl == NULL) { g_warning ("SSL_new() == NULL");