examples/lm-send-sync.c
changeset 310 8cfd2c340b9a
parent 309 329900413057
child 311 153357413e1b
equal deleted inserted replaced
309:329900413057 310:8cfd2c340b9a
     1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
       
     2 /*
       
     3  * Copyright (C) 2004 Imendio AB
       
     4  *
       
     5  * This library is free software; you can redistribute it and/or
       
     6  * modify it under the terms of the GNU Library General Public
       
     7  * License as published by the Free Software Foundation; either
       
     8  * version 2 of the License, or (at your option) any later version.
       
     9  *
       
    10  * This library is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13  * Library General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU Library General Public
       
    16  * License along with this library; if not, write to the
       
    17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    18  * Boston, MA 02111-1307, USA.
       
    19  */
       
    20 
       
    21 /*
       
    22  * Description:
       
    23  * A little program that let you send jabber messages to another person.
       
    24  * 
       
    25  * Build instructions:
       
    26  * gcc -o lm-send-sync `pkg-config --cflags --libs loudmouth-1.0` lm-send-sync.c
       
    27  */
       
    28 
       
    29 #include <string.h>
       
    30 #include <stdlib.h>
       
    31 
       
    32 #include <loudmouth/loudmouth.h>
       
    33 
       
    34 static gchar      expected_fingerprint[20];
       
    35 
       
    36 static gchar     *server = NULL;
       
    37 static gint       port = 5222;
       
    38 static gchar     *username = NULL;
       
    39 static gchar     *password = NULL;
       
    40 static gchar     *resource = "lm-send-sync";
       
    41 static gchar     *recipient = NULL;
       
    42 static gchar     *fingerprint = NULL;
       
    43 static gchar     *message = "test synchronous message";
       
    44 
       
    45 static GOptionEntry entries[] = 
       
    46 {
       
    47   { "server", 's', 0, G_OPTION_ARG_STRING, &server, 
       
    48     "Server to connect to", NULL },
       
    49   { "port", 'P', 0, G_OPTION_ARG_INT, &port, 
       
    50     "Port to connect to [default=5222]", NULL },
       
    51   { "username", 'u', 0, G_OPTION_ARG_STRING, &username, 
       
    52     "Username to connect with (e.g. 'user' in user@server.org)", NULL },
       
    53   { "password", 'p', 0, G_OPTION_ARG_STRING, &password, 
       
    54     "Password to try", NULL },
       
    55   { "resource", 'r', 0, G_OPTION_ARG_STRING, &resource, 
       
    56     "Resource connect with [default=lm-send-sync]", NULL },
       
    57   { "recipient", 'R', 0, G_OPTION_ARG_STRING, &recipient, 
       
    58     "Recipient to send the message to (e.g. user@server.org)", NULL },
       
    59   { "fingerprint", 'f', 0, G_OPTION_ARG_STRING, &fingerprint, 
       
    60     "SSL Fingerprint to use", NULL },
       
    61   { "message", 'm', 0, G_OPTION_ARG_STRING, &message, 
       
    62     "Message to send to recipient [default=test synchronous message]", NULL },
       
    63   { NULL }
       
    64 };
       
    65 
       
    66 static gchar *
       
    67 get_part_name (const gchar *username)
       
    68 {
       
    69 	const gchar *ch;
       
    70 
       
    71 	g_return_val_if_fail (username != NULL, NULL);
       
    72 
       
    73 	ch = strchr (username, '@');
       
    74 	if (!ch) {
       
    75 		return NULL;
       
    76 	}
       
    77 
       
    78 	return g_strndup (username, ch - username);
       
    79 }
       
    80 
       
    81 static void
       
    82 print_finger (const char   *fpr,
       
    83 	      unsigned int  size)
       
    84 {
       
    85 	gint i;
       
    86 	for (i = 0; i < size-1; i++) {
       
    87 		g_printerr ("%02X:", fpr[i]);
       
    88 	}
       
    89 	
       
    90 	g_printerr ("%02X", fpr[size-1]);
       
    91 }
       
    92 
       
    93 static LmSSLResponse
       
    94 ssl_cb (LmSSL       *ssl, 
       
    95 	LmSSLStatus  status, 
       
    96 	gpointer     ud)
       
    97 {
       
    98 	g_print ("LmSendSync: SSL status:%d\n", status);
       
    99 
       
   100 	switch (status) {
       
   101 	case LM_SSL_STATUS_NO_CERT_FOUND:
       
   102 		g_printerr ("LmSendSync: No certificate found!\n");
       
   103 		break;
       
   104 	case LM_SSL_STATUS_UNTRUSTED_CERT:
       
   105 		g_printerr ("LmSendSync: Certificate is not trusted!\n"); 
       
   106 		break;
       
   107 	case LM_SSL_STATUS_CERT_EXPIRED:
       
   108 		g_printerr ("LmSendSync: Certificate has expired!\n"); 
       
   109 		break;
       
   110 	case LM_SSL_STATUS_CERT_NOT_ACTIVATED:
       
   111 		g_printerr ("LmSendSync: Certificate has not been activated!\n"); 
       
   112 		break;
       
   113 	case LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH:
       
   114 		g_printerr ("LmSendSync: Certificate hostname does not match expected hostname!\n"); 
       
   115 		break;
       
   116 	case LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH: {
       
   117 		const char *fpr = lm_ssl_get_fingerprint (ssl);
       
   118 		g_printerr ("LmSendSync: Certificate fingerprint does not match expected fingerprint!\n"); 
       
   119 		g_printerr ("LmSendSync: Remote fingerprint: ");
       
   120 		print_finger (fpr, 16);
       
   121 
       
   122 		g_printerr ("\n"
       
   123 			    "LmSendSync: Expected fingerprint: ");
       
   124 		print_finger (expected_fingerprint, 16);
       
   125 		g_printerr ("\n");
       
   126 		break;
       
   127 	}
       
   128 	case LM_SSL_STATUS_GENERIC_ERROR:
       
   129 		g_printerr ("LmSendSync: Generic SSL error!\n"); 
       
   130 		break;
       
   131 	}
       
   132 
       
   133 	return LM_SSL_RESPONSE_CONTINUE;
       
   134 }
       
   135 
       
   136 int
       
   137 main (int argc, char **argv)
       
   138 {
       
   139 	GOptionContext *context;
       
   140 	GError         *error = NULL;
       
   141         LmConnection   *connection;
       
   142 	LmMessage      *m;
       
   143 	gchar          *user;
       
   144 
       
   145 	context = g_option_context_new ("- test send message synchronously");
       
   146 	g_option_context_add_main_entries (context, entries, NULL);
       
   147 	g_option_context_parse (context, &argc, &argv, NULL);
       
   148 	g_option_context_free (context);
       
   149 	
       
   150 	if (!username || !password || !recipient) {
       
   151 		g_printerr ("For usage, try %s --help\n", argv[0]);
       
   152 		return EXIT_FAILURE;
       
   153 	}
       
   154 
       
   155 	if (username && strchr (username, '@') == NULL) {
       
   156 		g_printerr ("LmSendSync: Username must have an '@' included\n");
       
   157 		return EXIT_FAILURE;
       
   158 	}
       
   159 
       
   160         connection = lm_connection_new (server);
       
   161 	lm_connection_set_port (connection, port);
       
   162 	lm_connection_set_jid (connection, username);
       
   163 
       
   164 	if (fingerprint) {
       
   165 		LmSSL *ssl;
       
   166 		char  *p;
       
   167 		int    i;
       
   168 		
       
   169 		if (port == LM_CONNECTION_DEFAULT_PORT) {
       
   170 			lm_connection_set_port (connection,
       
   171 						LM_CONNECTION_DEFAULT_PORT_SSL);
       
   172 		}
       
   173 
       
   174 		for (i = 0, p = fingerprint; *p && *(p+1); i++, p += 3) {
       
   175 			expected_fingerprint[i] = (unsigned char) g_ascii_strtoull (p, NULL, 16);
       
   176 		}
       
   177 	
       
   178 		ssl = lm_ssl_new (expected_fingerprint,
       
   179 				  (LmSSLFunction) ssl_cb,
       
   180 				  NULL, NULL);
       
   181 	
       
   182 		lm_connection_set_ssl (connection, ssl);
       
   183 		lm_ssl_unref (ssl);
       
   184 	}
       
   185 
       
   186         if (!lm_connection_open_and_block (connection, &error)) {
       
   187                 g_printerr ("LmSendSync: Could not open a connection: %s\n", error->message);
       
   188 		return EXIT_FAILURE;
       
   189         }
       
   190 
       
   191 	user = get_part_name (username);
       
   192 	if (!lm_connection_authenticate_and_block (connection,
       
   193 						   user, password, resource,
       
   194 						   &error)) {
       
   195 		g_free (user);
       
   196 		g_printerr ("LmSendSync: Failed to authenticate: %s\n", error->message);
       
   197 		return EXIT_FAILURE;
       
   198 	}
       
   199 	g_free (user);
       
   200 	
       
   201 	m = lm_message_new (recipient, LM_MESSAGE_TYPE_MESSAGE);
       
   202 	lm_message_node_add_child (m->node, "body", message);
       
   203 	
       
   204 	if (!lm_connection_send (connection, m, &error)) {
       
   205 		g_printerr ("LmSendSync: Failed to send message: %s\n", error->message);
       
   206 		return EXIT_FAILURE;
       
   207 	}
       
   208 
       
   209 	lm_message_unref (m);
       
   210 
       
   211 	lm_connection_close (connection, NULL);
       
   212 	lm_connection_unref (connection);
       
   213 	
       
   214 	return EXIT_SUCCESS;
       
   215 }
       
   216