examples/test-lm.c
changeset 518 cdd6a0c5b439
parent 517 6fabea75bea7
child 664 f57b1b61e1fe
equal deleted inserted replaced
517:6fabea75bea7 518:cdd6a0c5b439
    38 static gchar     *resource = "test-lm";
    38 static gchar     *resource = "test-lm";
    39 static gchar     *fingerprint = NULL;
    39 static gchar     *fingerprint = NULL;
    40 
    40 
    41 static GOptionEntry entries[] = 
    41 static GOptionEntry entries[] = 
    42 {
    42 {
    43   { "server", 's', 0, G_OPTION_ARG_STRING, &server, 
    43     { "server", 's', 0, G_OPTION_ARG_STRING, &server, 
    44     "Server to connect to", NULL },
    44       "Server to connect to", NULL },
    45   { "port", 'P', 0, G_OPTION_ARG_INT, &port, 
    45     { "port", 'P', 0, G_OPTION_ARG_INT, &port, 
    46     "Port to connect to [default=5222]", NULL },
    46       "Port to connect to [default=5222]", NULL },
    47   { "username", 'u', 0, G_OPTION_ARG_STRING, &username, 
    47     { "username", 'u', 0, G_OPTION_ARG_STRING, &username, 
    48     "Username to connect with (user@server.org)", NULL },
    48       "Username to connect with (user@server.org)", NULL },
    49   { "password", 'p', 0, G_OPTION_ARG_STRING, &password, 
    49     { "password", 'p', 0, G_OPTION_ARG_STRING, &password, 
    50     "Password to try", NULL },
    50       "Password to try", NULL },
    51   { "resource", 'r', 0, G_OPTION_ARG_STRING, &resource, 
    51     { "resource", 'r', 0, G_OPTION_ARG_STRING, &resource, 
    52     "Resource connect with [default=test-lm]", NULL },
    52       "Resource connect with [default=test-lm]", NULL },
    53   { "fingerprint", 'f', 0, G_OPTION_ARG_STRING, &fingerprint, 
    53     { "fingerprint", 'f', 0, G_OPTION_ARG_STRING, &fingerprint, 
    54     "SSL Fingerprint to use", NULL },
    54       "SSL Fingerprint to use", NULL },
    55   { NULL }
    55     { NULL }
    56 };
    56 };
    57 
    57 
    58 static gchar *
    58 static gchar *
    59 get_part_name (const gchar *username)
    59 get_part_name (const gchar *username)
    60 {
    60 {
    61 	const gchar *ch;
    61     const gchar *ch;
    62 
    62 
    63 	g_return_val_if_fail (username != NULL, NULL);
    63     g_return_val_if_fail (username != NULL, NULL);
    64 
    64 
    65 	ch = strchr (username, '@');
    65     ch = strchr (username, '@');
    66 	if (!ch) {
    66     if (!ch) {
    67 		return NULL;
    67         return NULL;
    68 	}
    68     }
    69 
    69 
    70 	return g_strndup (username, ch - username);
    70     return g_strndup (username, ch - username);
    71 }
    71 }
    72 
    72 
    73 static void
    73 static void
    74 print_finger (const char   *fpr,
    74 print_finger (const char   *fpr,
    75 	      unsigned int  size)
    75               unsigned int  size)
    76 {
    76 {
    77 	gint i;
    77     gint i;
    78 	for (i = 0; i < size-1; i++) {
    78     for (i = 0; i < size-1; i++) {
    79 		g_printerr ("%02X:", fpr[i]);
    79         g_printerr ("%02X:", fpr[i]);
    80 	}
    80     }
    81 	
    81     
    82 	g_printerr ("%02X", fpr[size-1]);
    82     g_printerr ("%02X", fpr[size-1]);
    83 }
    83 }
    84 
    84 
    85 static LmSSLResponse
    85 static LmSSLResponse
    86 ssl_cb (LmSSL       *ssl, 
    86 ssl_cb (LmSSL       *ssl, 
    87 	LmSSLStatus  status, 
    87         LmSSLStatus  status, 
    88 	gpointer     ud)
    88         gpointer     ud)
    89 {
    89 {
    90 	g_print ("TestLM: SSL status:%d\n", status);
    90     g_print ("TestLM: SSL status:%d\n", status);
    91 
    91 
    92 	switch (status) {
    92     switch (status) {
    93 	case LM_SSL_STATUS_NO_CERT_FOUND:
    93     case LM_SSL_STATUS_NO_CERT_FOUND:
    94 		g_printerr ("TestLM: No certificate found!\n");
    94         g_printerr ("TestLM: No certificate found!\n");
    95 		break;
    95         break;
    96 	case LM_SSL_STATUS_UNTRUSTED_CERT:
    96     case LM_SSL_STATUS_UNTRUSTED_CERT:
    97 		g_printerr ("TestLM: Certificate is not trusted!\n"); 
    97         g_printerr ("TestLM: Certificate is not trusted!\n"); 
    98 		break;
    98         break;
    99 	case LM_SSL_STATUS_CERT_EXPIRED:
    99     case LM_SSL_STATUS_CERT_EXPIRED:
   100 		g_printerr ("TestLM: Certificate has expired!\n"); 
   100         g_printerr ("TestLM: Certificate has expired!\n"); 
   101 		break;
   101         break;
   102 	case LM_SSL_STATUS_CERT_NOT_ACTIVATED:
   102     case LM_SSL_STATUS_CERT_NOT_ACTIVATED:
   103 		g_printerr ("TestLM: Certificate has not been activated!\n"); 
   103         g_printerr ("TestLM: Certificate has not been activated!\n"); 
   104 		break;
   104         break;
   105 	case LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH:
   105     case LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH:
   106 		g_printerr ("TestLM: Certificate hostname does not match expected hostname!\n"); 
   106         g_printerr ("TestLM: Certificate hostname does not match expected hostname!\n"); 
   107 		break;
   107         break;
   108 	case LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH: {
   108     case LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH: {
   109 		const char *fpr = lm_ssl_get_fingerprint (ssl);
   109         const char *fpr = lm_ssl_get_fingerprint (ssl);
   110 		g_printerr ("TestLM: Certificate fingerprint does not match expected fingerprint!\n"); 
   110         g_printerr ("TestLM: Certificate fingerprint does not match expected fingerprint!\n"); 
   111 		g_printerr ("TestLM: Remote fingerprint: ");
   111         g_printerr ("TestLM: Remote fingerprint: ");
   112 		print_finger (fpr, 16);
   112         print_finger (fpr, 16);
   113 
   113 
   114 		g_printerr ("\n"
   114         g_printerr ("\n"
   115 			    "TestLM: Expected fingerprint: ");
   115                     "TestLM: Expected fingerprint: ");
   116 		print_finger (expected_fingerprint, 16);
   116         print_finger (expected_fingerprint, 16);
   117 		g_printerr ("\n");
   117         g_printerr ("\n");
   118 		break;
   118         break;
   119 	}
   119     }
   120 	case LM_SSL_STATUS_GENERIC_ERROR:
   120     case LM_SSL_STATUS_GENERIC_ERROR:
   121 		g_printerr ("TestLM: Generic SSL error!\n"); 
   121         g_printerr ("TestLM: Generic SSL error!\n"); 
   122 		break;
   122         break;
   123 	}
   123     }
   124 
   124 
   125 	return LM_SSL_RESPONSE_CONTINUE;
   125     return LM_SSL_RESPONSE_CONTINUE;
   126 }
   126 }
   127 
   127 
   128 static void
   128 static void
   129 connection_auth_cb (LmConnection *connection,
   129 connection_auth_cb (LmConnection *connection,
   130 		    gboolean      success, 
   130                     gboolean      success, 
   131 		    gpointer      user_data)
   131                     gpointer      user_data)
   132 {
   132 {
   133 	if (success) {
   133     if (success) {
   134 		LmMessage *m;
   134         LmMessage *m;
   135 		
   135         
   136 		test_success = TRUE;
   136         test_success = TRUE;
   137 		g_print ("TestLM: Authenticated successfully\n");
   137         g_print ("TestLM: Authenticated successfully\n");
   138 
   138 
   139 		m = lm_message_new_with_sub_type (NULL,
   139         m = lm_message_new_with_sub_type (NULL,
   140 						  LM_MESSAGE_TYPE_PRESENCE,
   140                                           LM_MESSAGE_TYPE_PRESENCE,
   141 						  LM_MESSAGE_SUB_TYPE_AVAILABLE);
   141                                           LM_MESSAGE_SUB_TYPE_AVAILABLE);
   142 		lm_connection_send (connection, m, NULL);
   142         lm_connection_send (connection, m, NULL);
   143 		g_print ("TestLM: Sent presence message:'%s'\n", 
   143         g_print ("TestLM: Sent presence message:'%s'\n", 
   144 			 lm_message_node_to_string (m->node));
   144                  lm_message_node_to_string (m->node));
   145 
   145 
   146 		lm_message_unref (m);
   146         lm_message_unref (m);
   147 	} else {
   147     } else {
   148 		g_printerr ("TestLM: Failed to authenticate\n");
   148         g_printerr ("TestLM: Failed to authenticate\n");
   149 		g_main_loop_quit (main_loop);
   149         g_main_loop_quit (main_loop);
   150 	}
   150     }
   151 }
   151 }
   152 
   152 
   153 static void
   153 static void
   154 connection_open_cb (LmConnection *connection, 
   154 connection_open_cb (LmConnection *connection, 
   155 		    gboolean      success,
   155                     gboolean      success,
   156 		    gpointer      user_data)
   156                     gpointer      user_data)
   157 {
   157 {
   158 	if (success) {
   158     if (success) {
   159 		gchar *user;
   159         gchar *user;
   160 
   160 
   161 		user = get_part_name (username);
   161         user = get_part_name (username);
   162 		lm_connection_authenticate (connection, user, 
   162         lm_connection_authenticate (connection, user, 
   163 					    password, resource,
   163                                     password, resource,
   164 					    connection_auth_cb, 
   164                                     connection_auth_cb, 
   165 					    NULL, FALSE,  NULL);
   165                                     NULL, FALSE,  NULL);
   166 		g_free (user);
   166         g_free (user);
   167 		
   167         
   168 		g_print ("TestLM: Sent authentication message\n");
   168         g_print ("TestLM: Sent authentication message\n");
   169 	} else {
   169     } else {
   170 		g_printerr ("TestLM: Failed to connect\n");
   170         g_printerr ("TestLM: Failed to connect\n");
   171 		g_main_loop_quit (main_loop);
   171         g_main_loop_quit (main_loop);
   172 	}
   172     }
   173 }
   173 }
   174 
   174 
   175 static void
   175 static void
   176 connection_close_cb (LmConnection       *connection, 
   176 connection_close_cb (LmConnection       *connection, 
   177 		     LmDisconnectReason  reason,
   177                      LmDisconnectReason  reason,
   178 		     gpointer            user_data)
   178                      gpointer            user_data)
   179 {
   179 {
   180 	const char *str;
   180     const char *str;
   181 	
   181     
   182 	switch (reason) {
   182     switch (reason) {
   183 	case LM_DISCONNECT_REASON_OK:
   183     case LM_DISCONNECT_REASON_OK:
   184 		str = "LM_DISCONNECT_REASON_OK";
   184         str = "LM_DISCONNECT_REASON_OK";
   185 		break;
   185         break;
   186 	case LM_DISCONNECT_REASON_PING_TIME_OUT:
   186     case LM_DISCONNECT_REASON_PING_TIME_OUT:
   187 		str = "LM_DISCONNECT_REASON_PING_TIME_OUT";
   187         str = "LM_DISCONNECT_REASON_PING_TIME_OUT";
   188 		break;
   188         break;
   189 	case LM_DISCONNECT_REASON_HUP:
   189     case LM_DISCONNECT_REASON_HUP:
   190 		str = "LM_DISCONNECT_REASON_HUP";
   190         str = "LM_DISCONNECT_REASON_HUP";
   191 		break;
   191         break;
   192 	case LM_DISCONNECT_REASON_ERROR:
   192     case LM_DISCONNECT_REASON_ERROR:
   193 		str = "LM_DISCONNECT_REASON_ERROR";
   193         str = "LM_DISCONNECT_REASON_ERROR";
   194 		break;
   194         break;
   195 	case LM_DISCONNECT_REASON_UNKNOWN:
   195     case LM_DISCONNECT_REASON_UNKNOWN:
   196 	default:
   196     default:
   197 		str = "LM_DISCONNECT_REASON_UNKNOWN";
   197         str = "LM_DISCONNECT_REASON_UNKNOWN";
   198 		break;
   198         break;
   199 	}
   199     }
   200 
   200 
   201 	g_print ("TestLM: Disconnected, reason:%d->'%s'\n", reason, str);
   201     g_print ("TestLM: Disconnected, reason:%d->'%s'\n", reason, str);
   202 }
   202 }
   203 
   203 
   204 static LmHandlerResult
   204 static LmHandlerResult
   205 handle_messages (LmMessageHandler *handler,
   205 handle_messages (LmMessageHandler *handler,
   206 		 LmConnection     *connection,
   206                  LmConnection     *connection,
   207 		 LmMessage        *m,
   207                  LmMessage        *m,
   208 		 gpointer          user_data)
   208                  gpointer          user_data)
   209 {
   209 {
   210 	g_print ("TestLM: Incoming message from: %s\n",
   210     g_print ("TestLM: Incoming message from: %s\n",
   211 		 lm_message_node_get_attribute (m->node, "from"));
   211              lm_message_node_get_attribute (m->node, "from"));
   212 
   212 
   213 	return LM_HANDLER_RESULT_REMOVE_MESSAGE;
   213     return LM_HANDLER_RESULT_REMOVE_MESSAGE;
   214 }
   214 }
   215 
   215 
   216 int 
   216 int 
   217 main (int argc, char **argv)
   217 main (int argc, char **argv)
   218 {
   218 {
   219 	GOptionContext   *context;
   219     GOptionContext   *context;
   220 	LmConnection     *connection;
   220     LmConnection     *connection;
   221 	LmMessageHandler *handler;
   221     LmMessageHandler *handler;
   222 	gboolean          result;
   222     gboolean          result;
   223 	GError           *error = NULL;
   223     GError           *error = NULL;
   224 	
   224     
   225 	context = g_option_context_new ("- test Loudmouth");
   225     context = g_option_context_new ("- test Loudmouth");
   226 	g_option_context_add_main_entries (context, entries, NULL);
   226     g_option_context_add_main_entries (context, entries, NULL);
   227 	g_option_context_parse (context, &argc, &argv, NULL);
   227     g_option_context_parse (context, &argc, &argv, NULL);
   228 	g_option_context_free (context);
   228     g_option_context_free (context);
   229 	
   229     
   230 	if (!server || !username || !password) {
   230     if (!server || !username || !password) {
   231 		g_printerr ("For usage, try %s --help\n", argv[0]);
   231         g_printerr ("For usage, try %s --help\n", argv[0]);
   232 		return EXIT_FAILURE;
   232         return EXIT_FAILURE;
   233 	}
   233     }
   234 
   234 
   235 	if (fingerprint && !lm_ssl_is_supported ()) {
   235     if (fingerprint && !lm_ssl_is_supported ()) {
   236 		g_printerr ("TestLM: SSL is not supported in this build\n");
   236         g_printerr ("TestLM: SSL is not supported in this build\n");
   237 		return EXIT_FAILURE;
   237         return EXIT_FAILURE;
   238 	}
   238     }
   239 
   239 
   240 	if (username && strchr (username, '@') == NULL) {
   240     if (username && strchr (username, '@') == NULL) {
   241 		g_printerr ("TestLM: Username must have an '@' included\n");
   241         g_printerr ("TestLM: Username must have an '@' included\n");
   242 		return EXIT_FAILURE;
   242         return EXIT_FAILURE;
   243 	}
   243     }
   244 
   244 
   245         connection = lm_connection_new (server);
   245     connection = lm_connection_new (server);
   246 	lm_connection_set_port (connection, port);
   246     lm_connection_set_port (connection, port);
   247 	lm_connection_set_jid (connection, username);
   247     lm_connection_set_jid (connection, username);
   248 
   248 
   249 	handler = lm_message_handler_new (handle_messages, NULL, NULL);
   249     handler = lm_message_handler_new (handle_messages, NULL, NULL);
   250 	lm_connection_register_message_handler (connection, handler, 
   250     lm_connection_register_message_handler (connection, handler, 
   251 						LM_MESSAGE_TYPE_MESSAGE, 
   251                                             LM_MESSAGE_TYPE_MESSAGE, 
   252 						LM_HANDLER_PRIORITY_NORMAL);
   252                                             LM_HANDLER_PRIORITY_NORMAL);
   253 	
   253     
   254 	lm_message_handler_unref (handler);
   254     lm_message_handler_unref (handler);
   255 	
   255     
   256 	lm_connection_set_disconnect_function (connection,
   256     lm_connection_set_disconnect_function (connection,
   257 					       connection_close_cb,
   257                                            connection_close_cb,
   258 					       NULL, NULL);
   258                                            NULL, NULL);
   259 
   259 
   260 	if (fingerprint) {
   260     if (fingerprint) {
   261 		LmSSL *ssl;
   261         LmSSL *ssl;
   262 		char  *p;
   262         char  *p;
   263 		int    i;
   263         int    i;
   264 		
   264         
   265 		if (port == LM_CONNECTION_DEFAULT_PORT) {
   265         if (port == LM_CONNECTION_DEFAULT_PORT) {
   266 			lm_connection_set_port (connection,
   266             lm_connection_set_port (connection,
   267 						LM_CONNECTION_DEFAULT_PORT_SSL);
   267                                     LM_CONNECTION_DEFAULT_PORT_SSL);
   268 		}
   268         }
   269 
   269 
   270 		for (i = 0, p = fingerprint; *p && *(p+1); i++, p += 3) {
   270         for (i = 0, p = fingerprint; *p && *(p+1); i++, p += 3) {
   271 			expected_fingerprint[i] = (unsigned char) g_ascii_strtoull (p, NULL, 16);
   271             expected_fingerprint[i] = (unsigned char) g_ascii_strtoull (p, NULL, 16);
   272 		}
   272         }
   273 	
   273     
   274 		ssl = lm_ssl_new (expected_fingerprint,
   274         ssl = lm_ssl_new (expected_fingerprint,
   275 				  (LmSSLFunction) ssl_cb,
   275                           (LmSSLFunction) ssl_cb,
   276 				  NULL, NULL);
   276                           NULL, NULL);
   277 
   277 
   278                 lm_ssl_use_starttls (ssl, TRUE, FALSE);
   278         lm_ssl_use_starttls (ssl, TRUE, FALSE);
   279 	
   279     
   280 		lm_connection_set_ssl (connection, ssl);
   280         lm_connection_set_ssl (connection, ssl);
   281 		lm_ssl_unref (ssl);
   281         lm_ssl_unref (ssl);
   282 	}
   282     }
   283 
   283 
   284 	result = lm_connection_open (connection,
   284     result = lm_connection_open (connection,
   285 				     (LmResultFunction) connection_open_cb,
   285                                  (LmResultFunction) connection_open_cb,
   286 				     NULL, NULL, &error);
   286                                  NULL, NULL, &error);
   287 
   287 
   288 	if (!result) {
   288     if (!result) {
   289 		g_printerr ("TestLM: Opening connection failed, error:%d->'%s'\n", 
   289         g_printerr ("TestLM: Opening connection failed, error:%d->'%s'\n", 
   290 			 error->code, error->message);
   290                     error->code, error->message);
   291 		g_free (error);
   291         g_free (error);
   292 		return EXIT_FAILURE;
   292         return EXIT_FAILURE;
   293 	}
   293     }
   294 	
   294     
   295 	main_loop = g_main_loop_new (NULL, FALSE);
   295     main_loop = g_main_loop_new (NULL, FALSE);
   296 	g_main_loop_run (main_loop);
   296     g_main_loop_run (main_loop);
   297 
   297 
   298 	return (test_success ? EXIT_SUCCESS : EXIT_FAILURE);
   298     return (test_success ? EXIT_SUCCESS : EXIT_FAILURE);
   299 }
   299 }