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 |
|