2 #include <gio/gunixsocketaddress.h>
8 #include "gtlsconsoleinteraction.h"
12 gboolean verbose
= FALSE
;
13 gboolean non_blocking
= FALSE
;
14 gboolean use_udp
= FALSE
;
15 int cancel_timeout
= 0;
17 gboolean unix_socket
= FALSE
;
20 static GOptionEntry cmd_entries
[] = {
21 {"cancel", 'c', 0, G_OPTION_ARG_INT
, &cancel_timeout
,
22 "Cancel any op after the specified amount of seconds", NULL
},
23 {"udp", 'u', 0, G_OPTION_ARG_NONE
, &use_udp
,
24 "Use udp instead of tcp", NULL
},
25 {"verbose", 'v', 0, G_OPTION_ARG_NONE
, &verbose
,
27 {"non-blocking", 'n', 0, G_OPTION_ARG_NONE
, &non_blocking
,
28 "Enable non-blocking i/o", NULL
},
30 {"unix", 'U', 0, G_OPTION_ARG_NONE
, &unix_socket
,
31 "Use a unix socket instead of IP", NULL
},
33 {"timeout", 't', 0, G_OPTION_ARG_INT
, &read_timeout
,
34 "Time out reads after the specified number of seconds", NULL
},
35 {"tls", 'T', 0, G_OPTION_ARG_NONE
, &tls
,
36 "Use TLS (SSL)", NULL
},
40 #include "socket-common.c"
43 accept_certificate (GTlsClientConnection
*conn
,
44 GTlsCertificate
*cert
,
45 GTlsCertificateFlags errors
,
48 g_print ("Certificate would have been rejected ( ");
49 if (errors
& G_TLS_CERTIFICATE_UNKNOWN_CA
)
50 g_print ("unknown-ca ");
51 if (errors
& G_TLS_CERTIFICATE_BAD_IDENTITY
)
52 g_print ("bad-identity ");
53 if (errors
& G_TLS_CERTIFICATE_NOT_ACTIVATED
)
54 g_print ("not-activated ");
55 if (errors
& G_TLS_CERTIFICATE_EXPIRED
)
57 if (errors
& G_TLS_CERTIFICATE_REVOKED
)
59 if (errors
& G_TLS_CERTIFICATE_INSECURE
)
60 g_print ("insecure ");
61 g_print (") but accepting anyway.\n");
66 static GTlsCertificate
*
67 lookup_client_certificate (GTlsClientConnection
*conn
,
71 GList
*c
, *certificates
;
72 GTlsDatabase
*database
;
73 GTlsCertificate
*certificate
= NULL
;
76 accepted
= g_tls_client_connection_get_accepted_cas (conn
);
77 for (l
= accepted
; l
!= NULL
; l
= g_list_next (l
))
79 base
= G_TLS_CONNECTION (conn
);
80 database
= g_tls_connection_get_database (base
);
81 certificates
= g_tls_database_lookup_certificates_issued_by (database
, l
->data
,
82 g_tls_connection_get_interaction (base
),
83 G_TLS_DATABASE_LOOKUP_KEYPAIR
,
89 certificate
= g_object_ref (certificates
->data
);
91 for (c
= certificates
; c
!= NULL
; c
= g_list_next (c
))
92 g_object_unref (c
->data
);
93 g_list_free (certificates
);
96 for (l
= accepted
; l
!= NULL
; l
= g_list_next (l
))
97 g_byte_array_unref (l
->data
);
98 g_list_free (accepted
);
100 if (certificate
== NULL
&& error
&& !*error
)
101 g_set_error_literal (error
, G_TLS_ERROR
, G_TLS_ERROR_CERTIFICATE_REQUIRED
,
102 "Server requested a certificate, but could not find relevant certificate in database.");
107 make_connection (const char *argument
,
108 GTlsCertificate
*certificate
,
109 GCancellable
*cancellable
,
111 GSocketAddress
**address
,
112 GIOStream
**connection
,
113 GInputStream
**istream
,
114 GOutputStream
**ostream
,
117 GSocketType socket_type
;
118 GSocketFamily socket_family
;
119 GSocketAddressEnumerator
*enumerator
;
120 GSocketConnectable
*connectable
;
121 GSocketAddress
*src_address
;
122 GTlsInteraction
*interaction
;
126 socket_type
= G_SOCKET_TYPE_DATAGRAM
;
128 socket_type
= G_SOCKET_TYPE_STREAM
;
131 socket_family
= G_SOCKET_FAMILY_UNIX
;
133 socket_family
= G_SOCKET_FAMILY_IPV4
;
135 *socket
= g_socket_new (socket_family
, socket_type
, 0, error
);
140 g_socket_set_timeout (*socket
, read_timeout
);
144 GSocketAddress
*addr
;
146 addr
= socket_address_from_string (argument
);
149 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
150 "Could not parse '%s' as unix socket name", argument
);
153 connectable
= G_SOCKET_CONNECTABLE (addr
);
157 connectable
= g_network_address_parse (argument
, 7777, error
);
158 if (connectable
== NULL
)
162 enumerator
= g_socket_connectable_enumerate (connectable
);
165 *address
= g_socket_address_enumerator_next (enumerator
, cancellable
, error
);
166 if (*address
== NULL
)
168 if (error
!= NULL
&& *error
== NULL
)
169 g_set_error_literal (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
170 "No more addresses to try");
174 if (g_socket_connect (*socket
, *address
, cancellable
, &err
))
176 g_message ("Connection to %s failed: %s, trying next\n", socket_address_to_string (*address
), err
->message
);
177 g_clear_error (&err
);
179 g_object_unref (*address
);
181 g_object_unref (enumerator
);
183 g_print ("Connected to %s\n",
184 socket_address_to_string (*address
));
186 src_address
= g_socket_get_local_address (*socket
, error
);
189 g_prefix_error (error
, "Error getting local address: ");
193 g_print ("local address: %s\n",
194 socket_address_to_string (src_address
));
195 g_object_unref (src_address
);
204 *connection
= G_IO_STREAM (g_socket_connection_factory_create_connection (*socket
));
210 tls_conn
= g_tls_client_connection_new (*connection
, connectable
, error
);
213 g_prefix_error (error
, "Could not create TLS connection: ");
217 g_signal_connect (tls_conn
, "accept-certificate",
218 G_CALLBACK (accept_certificate
), NULL
);
220 interaction
= g_tls_console_interaction_new ();
221 g_tls_connection_set_interaction (G_TLS_CONNECTION (tls_conn
), interaction
);
222 g_object_unref (interaction
);
225 g_tls_connection_set_certificate (G_TLS_CONNECTION (tls_conn
), certificate
);
227 g_object_unref (*connection
);
228 *connection
= G_IO_STREAM (tls_conn
);
230 if (!g_tls_connection_handshake (G_TLS_CONNECTION (tls_conn
),
233 g_prefix_error (error
, "Error during TLS handshake: ");
237 g_object_unref (connectable
);
241 *istream
= g_io_stream_get_input_stream (*connection
);
242 *ostream
= g_io_stream_get_output_stream (*connection
);
253 GSocketAddress
*address
;
254 GError
*error
= NULL
;
255 GOptionContext
*context
;
256 GCancellable
*cancellable
;
257 GIOStream
*connection
;
258 GInputStream
*istream
;
259 GOutputStream
*ostream
;
260 GSocketAddress
*src_address
;
261 GTlsCertificate
*certificate
= NULL
;
267 context
= g_option_context_new (" <hostname>[:port] - Test GSocket client stuff");
268 g_option_context_add_main_entries (context
, cmd_entries
, NULL
);
269 if (!g_option_context_parse (context
, &argc
, &argv
, &error
))
271 g_printerr ("%s: %s\n", argv
[0], error
->message
);
277 g_printerr ("%s: %s\n", argv
[0], "Need to specify hostname / unix socket name");
283 g_printerr ("DTLS (TLS over UDP) is not supported");
290 cancellable
= g_cancellable_new ();
291 thread
= g_thread_new ("cancel", cancel_thread
, cancellable
);
292 g_thread_unref (thread
);
299 loop
= g_main_loop_new (NULL
, FALSE
);
301 for (i
= 0; i
< 2; i
++)
303 if (make_connection (argv
[1], certificate
, cancellable
, &socket
, &address
,
304 &connection
, &istream
, &ostream
, &error
))
307 if (g_error_matches (error
, G_TLS_ERROR
, G_TLS_ERROR_CERTIFICATE_REQUIRED
))
309 g_clear_error (&error
);
310 certificate
= lookup_client_certificate (G_TLS_CLIENT_CONNECTION (connection
), &error
);
311 if (certificate
!= NULL
)
315 g_printerr ("%s: %s", argv
[0], error
->message
);
319 /* TODO: Test non-blocking connect/handshake */
321 g_socket_set_blocking (socket
, FALSE
);
329 if (fgets (buffer
, sizeof buffer
, stdin
) == NULL
)
332 to_send
= strlen (buffer
);
337 ensure_socket_condition (socket
, G_IO_OUT
, cancellable
);
338 size
= g_socket_send_to (socket
, address
,
340 cancellable
, &error
);
344 ensure_connection_condition (connection
, G_IO_OUT
, cancellable
);
345 size
= g_output_stream_write (ostream
,
347 cancellable
, &error
);
352 if (g_error_matches (error
,
354 G_IO_ERROR_WOULD_BLOCK
))
356 g_print ("socket send would block, handling\n");
357 g_error_free (error
);
363 g_printerr ("Error sending to socket: %s\n",
369 g_print ("sent %" G_GSSIZE_FORMAT
" bytes of data\n", size
);
373 g_printerr ("Unexpected short write\n");
382 ensure_socket_condition (socket
, G_IO_IN
, cancellable
);
383 size
= g_socket_receive_from (socket
, &src_address
,
384 buffer
, sizeof buffer
,
385 cancellable
, &error
);
389 ensure_connection_condition (connection
, G_IO_IN
, cancellable
);
390 size
= g_input_stream_read (istream
,
391 buffer
, sizeof buffer
,
392 cancellable
, &error
);
397 g_printerr ("Error receiving from socket: %s\n",
405 g_print ("received %" G_GSSIZE_FORMAT
" bytes of data", size
);
407 g_print (" from %s", socket_address_to_string (src_address
));
411 g_print ("-------------------------\n"
413 "-------------------------\n",
418 g_print ("closing socket\n");
422 if (!g_io_stream_close (connection
, cancellable
, &error
))
424 g_printerr ("Error closing connection: %s\n",
428 g_object_unref (connection
);
432 if (!g_socket_close (socket
, &error
))
434 g_printerr ("Error closing master socket: %s\n",
440 g_object_unref (socket
);
441 g_object_unref (address
);