Fix license.
[gnutls.git] / src / cli.c
blobd167f5771f69982bd3f55999df675fb8f653ae7d
1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3 * Copyright (C) 2000,2001,2002,2003 Nikos Mavrogiannopoulos
5 * This file is part of GNUTLS.
7 * GNUTLS is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * GNUTLS is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <config.h>
23 #include <stdio.h>
24 #include <errno.h>
25 #include <stdlib.h>
26 #include <sys/types.h>
27 #include <string.h>
28 #include <sys/time.h>
29 #include <sys/stat.h>
30 #include <sys/socket.h>
31 #include <sys/select.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <error.h>
36 #include <gnutls/gnutls.h>
37 #include <gnutls/extra.h>
38 #include <gnutls/x509.h>
39 #include <gnutls/openpgp.h>
40 #include <gcrypt.h>
42 /* Gnulib portability files. */
43 #include <progname.h>
44 #include <version-etc.h>
45 #include <read-file.h>
46 #include <getpass.h>
47 #include <minmax.h>
48 #include "sockets.h"
50 #include "common.h"
51 #include "cli-gaa.h"
53 #define MAX_BUF 4096
55 /* global stuff here */
56 int resume, starttls, insecure, rehandshake;
57 const char *hostname = NULL;
58 char *service;
59 int record_max_size;
60 int fingerprint;
61 int crlf;
62 int verbose = 0;
63 extern int print_cert;
65 char *srp_passwd = NULL;
66 char *srp_username;
67 char *pgp_keyfile;
68 char *pgp_certfile;
69 char *pgp_keyring;
70 char *x509_keyfile;
71 char *x509_certfile;
72 char *x509_cafile;
73 char *x509_crlfile = NULL;
74 static int x509ctype;
75 static int disable_extensions;
77 char *psk_username = NULL;
78 gnutls_datum_t psk_key = { NULL, 0 };
80 static gnutls_srp_client_credentials_t srp_cred;
81 static gnutls_psk_client_credentials_t psk_cred;
82 static gnutls_anon_client_credentials_t anon_cred;
83 static gnutls_certificate_credentials_t xcred;
85 static gaainfo info;
87 static int protocol_priority[PRI_MAX];
88 static int kx_priority[PRI_MAX];
89 static int cipher_priority[PRI_MAX];
90 static int comp_priority[PRI_MAX];
91 static int mac_priority[PRI_MAX];
92 static int cert_type_priority[PRI_MAX];
94 /* end of global stuff */
96 /* prototypes */
97 typedef struct
99 int fd;
100 gnutls_session_t session;
101 int secure;
102 char *hostname;
103 char *ip;
104 char *service;
105 struct addrinfo *ptr;
106 struct addrinfo *addr_info;
107 } socket_st;
109 ssize_t socket_recv (const socket_st * socket, void *buffer, int buffer_size);
110 ssize_t socket_send (const socket_st * socket, const void *buffer,
111 int buffer_size);
112 void socket_open (socket_st * hd, const char *hostname, const char *service);
113 void socket_connect (const socket_st * hd);
114 void socket_bye (socket_st * socket);
116 static void check_rehandshake (socket_st * socket, int ret);
117 static int do_handshake (socket_st * socket);
118 static void init_global_tls_stuff (void);
120 /* Helper functions to load a certificate and key
121 * files into memory.
123 static gnutls_datum_t
124 load_file (const char *file)
126 gnutls_datum_t loaded_file = { NULL, 0 };
127 size_t length;
129 loaded_file.data = read_binary_file (file, &length);
130 if (loaded_file.data)
131 loaded_file.size = (unsigned int) length;
133 return loaded_file;
136 static void
137 unload_file (gnutls_datum_t data)
139 free (data.data);
142 #define MAX_CRT 6
143 static unsigned int x509_crt_size;
144 static gnutls_x509_crt_t x509_crt[MAX_CRT];
145 static gnutls_x509_privkey_t x509_key = NULL;
147 static gnutls_openpgp_crt_t pgp_crt = NULL;
148 static gnutls_openpgp_privkey_t pgp_key = NULL;
150 static void
151 get_keyid (gnutls_openpgp_keyid_t keyid, const char *str)
153 size_t keyid_size = sizeof (keyid);
155 if (strlen (str) != 16)
157 fprintf (stderr,
158 "The OpenPGP subkey ID has to be 16 hexadecimal characters.\n");
159 exit (1);
162 if (gnutls_hex2bin (str, strlen (str), keyid, &keyid_size) < 0)
164 fprintf (stderr, "Error converting hex string: %s.\n", str);
165 exit (1);
168 return;
171 /* Load the certificate and the private key.
173 static void
174 load_keys (void)
176 unsigned int crt_num;
177 int ret;
178 gnutls_datum_t data;
180 if (x509_certfile != NULL && x509_keyfile != NULL)
182 data = load_file (x509_certfile);
183 if (data.data == NULL)
185 fprintf (stderr, "*** Error loading cert file.\n");
186 exit (1);
189 crt_num = MAX_CRT;
190 ret =
191 gnutls_x509_crt_list_import (x509_crt, &crt_num, &data,
192 GNUTLS_X509_FMT_PEM,
193 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
194 if (ret < 0)
196 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
198 fprintf (stderr,
199 "*** Error loading cert file: Too many certs %d\n",
200 crt_num);
203 else
205 fprintf (stderr,
206 "*** Error loading cert file: %s\n",
207 gnutls_strerror (ret));
209 exit (1);
211 x509_crt_size = ret;
212 fprintf (stderr, "Processed %d client certificates...\n", ret);
214 unload_file (data);
216 data = load_file (x509_keyfile);
217 if (data.data == NULL)
219 fprintf (stderr, "*** Error loading key file.\n");
220 exit (1);
223 gnutls_x509_privkey_init (&x509_key);
225 ret = gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM);
226 if (ret < 0)
228 fprintf (stderr, "*** Error loading key file: %s\n",
229 gnutls_strerror (ret));
230 exit (1);
233 unload_file (data);
235 fprintf (stderr, "Processed %d client X.509 certificates...\n",
236 x509_crt_size);
238 #ifdef ENABLE_OPENPGP
239 if (pgp_certfile != NULL && pgp_keyfile != NULL)
241 data = load_file (pgp_certfile);
242 if (data.data == NULL)
244 fprintf (stderr, "*** Error loading PGP cert file.\n");
245 exit (1);
247 gnutls_openpgp_crt_init (&pgp_crt);
249 ret =
250 gnutls_openpgp_crt_import (pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64);
251 if (ret < 0)
253 fprintf (stderr,
254 "*** Error loading PGP cert file: %s\n",
255 gnutls_strerror (ret));
256 exit (1);
260 unload_file (data);
262 data = load_file (pgp_keyfile);
263 if (data.data == NULL)
265 fprintf (stderr, "*** Error loading PGP key file.\n");
266 exit (1);
269 gnutls_openpgp_privkey_init (&pgp_key);
271 ret =
272 gnutls_openpgp_privkey_import (pgp_key, &data,
273 GNUTLS_OPENPGP_FMT_BASE64, NULL, 0);
274 if (ret < 0)
276 fprintf (stderr,
277 "*** Error loading PGP key file: %s\n",
278 gnutls_strerror (ret));
279 exit (1);
282 unload_file (data);
284 if (info.pgp_subkey != NULL)
286 gnutls_openpgp_keyid_t keyid;
288 if (strcasecmp (info.pgp_subkey, "auto") == 0)
290 ret = gnutls_openpgp_crt_get_auth_subkey (pgp_crt, keyid, 1);
291 if (ret < 0)
293 fprintf (stderr,
294 "*** Error setting preferred sub key id (%s): %s\n",
295 info.pgp_subkey, gnutls_strerror (ret));
296 exit (1);
299 else
300 get_keyid (keyid, info.pgp_subkey);
302 ret = gnutls_openpgp_crt_set_preferred_key_id (pgp_crt, keyid);
303 if (ret >= 0)
304 ret =
305 gnutls_openpgp_privkey_set_preferred_key_id (pgp_key, keyid);
306 if (ret < 0)
308 fprintf (stderr,
309 "*** Error setting preferred sub key id (%s): %s\n",
310 info.pgp_subkey, gnutls_strerror (ret));
311 exit (1);
315 fprintf (stderr, "Processed 1 client PGP certificate...\n");
317 #endif
323 /* This callback should be associated with a session by calling
324 * gnutls_certificate_client_set_retrieve_function( session, cert_callback),
325 * before a handshake.
328 static int
329 cert_callback (gnutls_session_t session,
330 const gnutls_datum_t * req_ca_rdn, int nreqs,
331 const gnutls_pk_algorithm_t * sign_algos,
332 int sign_algos_length, gnutls_retr_st * st)
334 char issuer_dn[256];
335 int i, ret;
336 size_t len;
338 if (verbose)
341 /* Print the server's trusted CAs
343 if (nreqs > 0)
344 printf ("- Server's trusted authorities:\n");
345 else
346 printf ("- Server did not send us any trusted authorities names.\n");
348 /* print the names (if any) */
349 for (i = 0; i < nreqs; i++)
351 len = sizeof (issuer_dn);
352 ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len);
353 if (ret >= 0)
355 printf (" [%d]: ", i);
356 printf ("%s\n", issuer_dn);
361 /* Select a certificate and return it.
362 * The certificate must be of any of the "sign algorithms"
363 * supported by the server.
366 st->type = gnutls_certificate_type_get (session);
369 st->ncerts = 0;
371 if (st->type == GNUTLS_CRT_X509)
373 gnutls_sign_algorithm_t cert_algo, req_algo;
374 int i, match = 0;
376 if (x509_crt[0] != NULL)
378 ret = gnutls_x509_crt_get_signature_algorithm (x509_crt[0]);
379 if (ret < 0)
381 /* error reading signature algorithm */
382 return -1;
384 cert_algo = ret;
386 i = 0;
389 ret =
390 gnutls_sign_algorithm_get_requested (session, i, &req_algo);
391 if (ret >= 0 && cert_algo == req_algo)
393 match = 1;
394 break;
397 /* server has not requested anything specific */
398 if (i == 0 && ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
400 match = 1;
401 break;
403 i++;
405 while (ret >= 0);
407 if (match == 0)
409 printf
410 ("- Could not find a suitable certificate to send to server\n");
411 return -1;
415 if (x509_crt != NULL && x509_key != NULL)
417 st->ncerts = x509_crt_size;
419 st->cert.x509 = x509_crt;
420 st->key.x509 = x509_key;
422 st->deinit_all = 0;
424 return 0;
427 else if (st->type == GNUTLS_CRT_OPENPGP)
429 if (pgp_key != NULL && pgp_crt != NULL)
431 st->ncerts = 1;
433 st->cert.pgp = pgp_crt;
434 st->key.pgp = pgp_key;
436 st->deinit_all = 0;
438 return 0;
442 printf ("- Successfully sent %d certificate(s) to server.\n", st->ncerts);
443 return 0;
447 /* initializes a gnutls_session_t with some defaults.
449 static gnutls_session_t
450 init_tls_session (const char *hostname)
452 const char *err;
454 gnutls_session_t session;
456 gnutls_init (&session, GNUTLS_CLIENT);
458 if (gnutls_priority_set_direct (session, info.priorities, &err) < 0)
460 fprintf (stderr, "Syntax error at: %s\n", err);
461 exit (1);
464 /* allow the use of private ciphersuites.
466 if (disable_extensions == 0)
468 gnutls_handshake_set_private_extensions (session, 1);
469 gnutls_server_name_set (session, GNUTLS_NAME_DNS, hostname,
470 strlen (hostname));
471 if (cert_type_priority[0])
472 gnutls_certificate_type_set_priority (session, cert_type_priority);
475 if (cipher_priority[0])
476 gnutls_cipher_set_priority (session, cipher_priority);
477 if (comp_priority[0])
478 gnutls_compression_set_priority (session, comp_priority);
479 if (kx_priority[0])
480 gnutls_kx_set_priority (session, kx_priority);
481 if (protocol_priority[0])
482 gnutls_protocol_set_priority (session, protocol_priority);
483 if (mac_priority[0])
484 gnutls_mac_set_priority (session, mac_priority);
486 gnutls_dh_set_prime_bits (session, 512);
488 gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred);
489 if (srp_cred)
490 gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred);
491 if (psk_cred)
492 gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred);
493 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
495 gnutls_certificate_client_set_retrieve_function (xcred, cert_callback);
497 /* send the fingerprint */
498 #ifdef ENABLE_OPENPGP
499 if (fingerprint != 0)
500 gnutls_openpgp_send_cert (session, GNUTLS_OPENPGP_CERT_FINGERPRINT);
501 #endif
503 /* use the max record size extension */
504 if (record_max_size > 0 && disable_extensions == 0)
506 if (gnutls_record_set_max_size (session, record_max_size) < 0)
508 fprintf (stderr,
509 "Cannot set the maximum record size to %d.\n",
510 record_max_size);
511 fprintf (stderr, "Possible values: 512, 1024, 2048, 4096.\n");
512 exit (1);
516 #ifdef ENABLE_OPRFI
517 if (info.opaque_prf_input)
518 gnutls_oprfi_enable_client (session, strlen (info.opaque_prf_input),
519 info.opaque_prf_input);
520 #endif
522 #ifdef ENABLE_SESSION_TICKET
523 if (!info.noticket)
524 gnutls_session_ticket_enable_client (session);
525 #endif
527 return session;
530 static void gaa_parser (int argc, char **argv);
532 /* Returns zero if the error code was successfully handled.
534 static int
535 handle_error (socket_st * hd, int err)
537 int alert, ret;
538 const char *err_type, *str;
540 if (err >= 0)
541 return 0;
543 if (gnutls_error_is_fatal (err) == 0)
545 ret = 0;
546 err_type = "Non fatal";
548 else
550 ret = err;
551 err_type = "Fatal";
554 str = gnutls_strerror (err);
555 if (str == NULL)
556 str = str_unknown;
557 fprintf (stderr, "*** %s error: %s\n", err_type, str);
559 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
560 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
562 alert = gnutls_alert_get (hd->session);
563 str = gnutls_alert_get_name (alert);
564 if (str == NULL)
565 str = str_unknown;
566 printf ("*** Received alert [%d]: %s\n", alert, str);
568 /* In SRP if the alert is MISSING_SRP_USERNAME,
569 * we should read the username/password and
570 * call gnutls_handshake(). This is not implemented
571 * here.
575 check_rehandshake (hd, err);
577 return ret;
580 int starttls_alarmed = 0;
582 static void
583 starttls_alarm (int signum)
585 starttls_alarmed = 1;
588 static void
589 tls_log_func (int level, const char *str)
591 fprintf (stderr, "|<%d>| %s", level, str);
595 main (int argc, char **argv)
597 int err, ret;
598 int ii, i;
599 char buffer[MAX_BUF + 1];
600 char *session_data = NULL;
601 char *session_id = NULL;
602 size_t session_data_size;
603 size_t session_id_size;
604 fd_set rset;
605 int maxfd;
606 struct timeval tv;
607 int user_term = 0, retval = 0;
608 socket_st hd;
609 ssize_t bytes;
611 set_program_name (argv[0]);
613 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
615 #ifdef gcry_fips_mode_active
616 /* Libgcrypt manual says that gcry_version_check must be called
617 before calling gcry_fips_mode_active. */
618 gcry_check_version (NULL);
619 if (gcry_fips_mode_active ())
621 ret = gnutls_register_md5_handler ();
622 if (ret)
623 fprintf (stderr, "gnutls_register_md5_handler: %s\n",
624 gnutls_strerror (ret));
626 #endif
628 if ((ret = gnutls_global_init ()) < 0)
630 fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
631 exit (1);
634 if ((ret = gnutls_global_init_extra ()) < 0)
636 fprintf (stderr, "global_init_extra: %s\n", gnutls_strerror (ret));
637 exit (1);
640 gaa_parser (argc, argv);
641 if (hostname == NULL)
643 fprintf (stderr, "No hostname given\n");
644 exit (1);
647 gnutls_global_set_log_function (tls_log_func);
648 gnutls_global_set_log_level (info.debug);
650 sockets_init ();
652 #ifndef _WIN32
653 signal (SIGPIPE, SIG_IGN);
654 #endif
656 init_global_tls_stuff ();
658 socket_open (&hd, hostname, service);
659 socket_connect (&hd);
661 hd.session = init_tls_session (hostname);
662 if (starttls)
663 goto after_handshake;
665 for (i = 0; i < 2; i++)
669 if (i == 1)
671 hd.session = init_tls_session (hostname);
672 gnutls_session_set_data (hd.session, session_data,
673 session_data_size);
674 free (session_data);
677 ret = do_handshake (&hd);
679 if (ret < 0)
681 fprintf (stderr, "*** Handshake has failed\n");
682 gnutls_perror (ret);
683 gnutls_deinit (hd.session);
684 return 1;
686 else
688 printf ("- Handshake was completed\n");
689 if (gnutls_session_is_resumed (hd.session) != 0)
690 printf ("*** This is a resumed session\n");
693 if (resume != 0 && i == 0)
696 gnutls_session_get_data (hd.session, NULL, &session_data_size);
697 session_data = malloc (session_data_size);
699 gnutls_session_get_data (hd.session, session_data,
700 &session_data_size);
702 gnutls_session_get_id (hd.session, NULL, &session_id_size);
703 session_id = malloc (session_id_size);
704 gnutls_session_get_id (hd.session, session_id, &session_id_size);
706 /* print some information */
707 print_info (hd.session, hostname, info.insecure);
709 printf ("- Disconnecting\n");
710 socket_bye (&hd);
712 printf
713 ("\n\n- Connecting again- trying to resume previous session\n");
714 socket_open (&hd, hostname, service);
715 socket_connect (&hd);
717 else
719 break;
723 after_handshake:
725 /* Warning! Do not touch this text string, it is used by external
726 programs to search for when gnutls-cli has reached this point. */
727 printf ("\n- Simple Client Mode:\n\n");
729 if (rehandshake)
731 ret = do_handshake (&hd);
733 if (ret < 0)
735 fprintf (stderr, "*** ReHandshake has failed\n");
736 gnutls_perror (ret);
737 gnutls_deinit (hd.session);
738 return 1;
740 else
742 printf ("- ReHandshake was completed\n");
746 #ifndef _WIN32
747 signal (SIGALRM, &starttls_alarm);
748 #endif
750 /* do not buffer */
751 #if !(defined _WIN32 || defined __WIN32__)
752 setbuf (stdin, NULL);
753 #endif
754 setbuf (stdout, NULL);
755 setbuf (stderr, NULL);
757 for (;;)
759 if (starttls_alarmed && !hd.secure)
761 /* Warning! Do not touch this text string, it is used by
762 external programs to search for when gnutls-cli has
763 reached this point. */
764 fprintf (stderr, "*** Starting TLS handshake\n");
765 ret = do_handshake (&hd);
766 if (ret < 0)
768 fprintf (stderr, "*** Handshake has failed\n");
769 user_term = 1;
770 retval = 1;
771 break;
775 FD_ZERO (&rset);
776 FD_SET (fileno (stdin), &rset);
777 FD_SET (hd.fd, &rset);
779 maxfd = MAX (fileno (stdin), hd.fd);
780 tv.tv_sec = 3;
781 tv.tv_usec = 0;
783 err = select (maxfd + 1, &rset, NULL, NULL, &tv);
784 if (err < 0)
785 continue;
787 if (FD_ISSET (hd.fd, &rset))
789 memset (buffer, 0, MAX_BUF + 1);
790 ret = socket_recv (&hd, buffer, MAX_BUF);
792 if (ret == 0)
794 printf ("- Peer has closed the GNUTLS connection\n");
795 break;
797 else if (handle_error (&hd, ret) < 0 && user_term == 0)
799 fprintf (stderr,
800 "*** Server has terminated the connection abnormally.\n");
801 retval = 1;
802 break;
804 else if (ret > 0)
806 if (verbose != 0)
807 printf ("- Received[%d]: ", ret);
808 for (ii = 0; ii < ret; ii++)
810 fputc (buffer[ii], stdout);
812 fflush (stdout);
815 if (user_term != 0)
816 break;
819 if (FD_ISSET (fileno (stdin), &rset))
821 if ((bytes = read (fileno(stdin), buffer, MAX_BUF - 1)) < 0)
823 if (hd.secure == 0)
825 /* Warning! Do not touch this text string, it is
826 used by external programs to search for when
827 gnutls-cli has reached this point. */
828 fprintf (stderr, "*** Starting TLS handshake\n");
829 ret = do_handshake (&hd);
830 clearerr (stdin);
831 if (ret < 0)
833 fprintf (stderr, "*** Handshake has failed\n");
834 user_term = 1;
835 retval = 1;
836 break;
839 else
841 user_term = 1;
842 break;
844 continue;
847 if (crlf != 0)
849 char *b = strchr (buffer, '\n');
850 if (b != NULL)
852 strcpy (b, "\r\n");
853 bytes++;
857 ret = socket_send (&hd, buffer, bytes);
859 if (ret > 0)
861 if (verbose != 0)
862 printf ("- Sent: %d bytes\n", ret);
864 else
865 handle_error (&hd, ret);
870 if (info.debug)
871 gcry_control (GCRYCTL_DUMP_RANDOM_STATS);
873 if (user_term != 0)
874 socket_bye (&hd);
875 else
876 gnutls_deinit (hd.session);
878 #ifdef ENABLE_SRP
879 if (srp_cred)
880 gnutls_srp_free_client_credentials (srp_cred);
881 #endif
882 #ifdef ENABLE_PSK
883 if (psk_cred)
884 gnutls_psk_free_client_credentials (psk_cred);
885 #endif
887 gnutls_certificate_free_credentials (xcred);
889 #ifdef ENABLE_ANON
890 gnutls_anon_free_client_credentials (anon_cred);
891 #endif
893 gnutls_global_deinit ();
895 return retval;
898 void
899 gaa_parser (int argc, char **argv)
901 if (gaa (argc, argv, &info) != -1)
903 fprintf (stderr,
904 "Error in the arguments. Use the --help or -h parameters to get more information.\n");
905 exit (1);
908 verbose = info.verbose;
909 disable_extensions = info.disable_extensions;
910 print_cert = info.print_cert;
911 starttls = info.starttls;
912 resume = info.resume;
913 rehandshake = info.rehandshake;
914 insecure = info.insecure;
915 service = info.port;
916 record_max_size = info.record_size;
917 fingerprint = info.fingerprint;
919 if (info.fmtder == 0)
920 x509ctype = GNUTLS_X509_FMT_PEM;
921 else
922 x509ctype = GNUTLS_X509_FMT_DER;
924 srp_username = info.srp_username;
925 srp_passwd = info.srp_passwd;
926 x509_cafile = info.x509_cafile;
927 x509_crlfile = info.x509_crlfile;
928 x509_keyfile = info.x509_keyfile;
929 x509_certfile = info.x509_certfile;
930 pgp_keyfile = info.pgp_keyfile;
931 pgp_certfile = info.pgp_certfile;
933 psk_username = info.psk_username;
934 psk_key.data = (unsigned char *) info.psk_key;
935 if (info.psk_key != NULL)
936 psk_key.size = strlen (info.psk_key);
937 else
938 psk_key.size = 0;
940 pgp_keyring = info.pgp_keyring;
942 crlf = info.crlf;
944 if (info.rest_args == NULL)
945 hostname = "localhost";
946 else
947 hostname = info.rest_args;
949 parse_protocols (info.proto, info.nproto, protocol_priority);
950 parse_ciphers (info.ciphers, info.nciphers, cipher_priority);
951 parse_macs (info.macs, info.nmacs, mac_priority);
952 parse_ctypes (info.ctype, info.nctype, cert_type_priority);
953 parse_kx (info.kx, info.nkx, kx_priority);
954 parse_comp (info.comp, info.ncomp, comp_priority);
957 void cli_version (void);
959 void
960 cli_version (void)
962 const char *p = PACKAGE_NAME;
963 if (strcmp (gnutls_check_version (NULL), PACKAGE_VERSION) != 0)
964 p = PACKAGE_STRING;
965 version_etc (stdout, program_name, p, gnutls_check_version (NULL),
966 "Nikos Mavrogiannopoulos", (char *) NULL);
970 static void
971 check_rehandshake (socket_st * socket, int ret)
973 if (socket->secure && ret == GNUTLS_E_REHANDSHAKE)
975 /* There is a race condition here. If application
976 * data is sent after the rehandshake request,
977 * the server thinks we ignored his request.
978 * This is a bad design of this client.
980 printf ("*** Received rehandshake request\n");
981 /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
983 ret = do_handshake (socket);
985 if (ret == 0)
987 printf ("*** Rehandshake was performed.\n");
989 else
991 printf ("*** Rehandshake Failed.\n");
997 static int
998 do_handshake (socket_st * socket)
1000 int ret;
1002 gnutls_transport_set_ptr (socket->session,
1003 (gnutls_transport_ptr_t)
1004 gl_fd_to_handle (socket->fd));
1007 ret = gnutls_handshake (socket->session);
1009 if (ret < 0)
1011 handle_error (socket, ret);
1014 while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
1016 if (ret == 0)
1018 /* print some information */
1019 print_info (socket->session, socket->hostname, info.insecure);
1021 if ((x509_cafile || pgp_keyring) && !insecure)
1023 int rc;
1024 unsigned int status;
1026 /* abort if verification fail */
1027 rc = gnutls_certificate_verify_peers2 (socket->session, &status);
1028 if (rc != 0 || status != 0)
1030 printf ("*** Verifying server certificate failed...\n");
1031 exit (1);
1035 socket->secure = 1;
1038 return ret;
1041 static int
1042 srp_username_callback (gnutls_session_t session,
1043 char **username, char **password)
1045 if (srp_username == NULL || srp_passwd == NULL)
1047 return -1;
1050 *username = gnutls_strdup (srp_username);
1051 *password = gnutls_strdup (srp_passwd);
1053 return 0;
1056 static int
1057 psk_callback (gnutls_session_t session, char **username, gnutls_datum_t * key)
1059 const char *hint = gnutls_psk_client_get_hint (session);
1060 char *passwd;
1061 int ret;
1063 printf ("- PSK client callback. ");
1064 if (hint)
1065 printf ("PSK hint '%s'\n", hint);
1066 else
1067 printf ("No PSK hint\n");
1069 if (info.psk_username)
1070 *username = gnutls_strdup (info.psk_username);
1071 else
1073 char *tmp = NULL;
1074 size_t n;
1075 ssize_t len;
1077 printf ("Enter PSK identity: ");
1078 fflush (stdout);
1079 len = getline (&tmp, &n, stdin);
1081 if (tmp == NULL)
1083 fprintf (stderr, "No username given, aborting...\n");
1084 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1087 if (tmp[strlen (tmp) - 1] == '\n')
1088 tmp[strlen (tmp) - 1] = '\0';
1089 if (tmp[strlen (tmp) - 1] == '\r')
1090 tmp[strlen (tmp) - 1] = '\0';
1092 *username = gnutls_strdup (tmp);
1093 free (tmp);
1095 if (!*username)
1096 return GNUTLS_E_MEMORY_ERROR;
1098 passwd = getpass ("Enter password: ");
1099 if (passwd == NULL)
1101 fprintf (stderr, "No password given, aborting...\n");
1102 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1105 ret = gnutls_psk_netconf_derive_key (passwd,
1106 *username, hint ? hint : "", key);
1107 if (ret < 0)
1109 fprintf (stderr, "Error deriving password: %s\n",
1110 gnutls_strerror (ret));
1111 gnutls_free (*username);
1112 return ret;
1115 if (info.debug)
1117 char hexkey[41];
1118 size_t res_size = sizeof (hexkey);
1119 gnutls_hex_encode (key, hexkey, &res_size);
1120 fprintf (stderr, "PSK username: %s\n", *username);
1121 fprintf (stderr, "PSK hint: %s\n", hint);
1122 fprintf (stderr, "PSK key: %s\n", hexkey);
1125 return 0;
1128 static void
1129 init_global_tls_stuff (void)
1131 int ret;
1133 /* X509 stuff */
1134 if (gnutls_certificate_allocate_credentials (&xcred) < 0)
1136 fprintf (stderr, "Certificate allocation memory error\n");
1137 exit (1);
1140 if (x509_cafile != NULL)
1142 ret = gnutls_certificate_set_x509_trust_file (xcred,
1143 x509_cafile, x509ctype);
1144 if (ret < 0)
1146 fprintf (stderr, "Error setting the x509 trust file\n");
1148 else
1150 printf ("Processed %d CA certificate(s).\n", ret);
1153 #ifdef ENABLE_PKI
1154 if (x509_crlfile != NULL)
1156 ret = gnutls_certificate_set_x509_crl_file (xcred, x509_crlfile,
1157 x509ctype);
1158 if (ret < 0)
1160 fprintf (stderr, "Error setting the x509 CRL file\n");
1162 else
1164 printf ("Processed %d CRL(s).\n", ret);
1167 #endif
1169 load_keys ();
1171 #ifdef ENABLE_OPENPGP
1172 if (pgp_keyring != NULL)
1174 ret =
1175 gnutls_certificate_set_openpgp_keyring_file (xcred, pgp_keyring,
1176 GNUTLS_OPENPGP_FMT_BASE64);
1177 if (ret < 0)
1179 fprintf (stderr, "Error setting the OpenPGP keyring file\n");
1182 #endif
1184 #ifdef ENABLE_SRP
1185 if (srp_username && srp_passwd)
1187 /* SRP stuff */
1188 if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0)
1190 fprintf (stderr, "SRP authentication error\n");
1193 gnutls_srp_set_client_credentials_function (srp_cred,
1194 srp_username_callback);
1196 #endif
1198 #ifdef ENABLE_PSK
1199 /* PSK stuff */
1200 if (gnutls_psk_allocate_client_credentials (&psk_cred) < 0)
1202 fprintf (stderr, "PSK authentication error\n");
1205 if (psk_username && psk_key.data)
1207 ret = gnutls_psk_set_client_credentials (psk_cred,
1208 psk_username, &psk_key,
1209 GNUTLS_PSK_KEY_HEX);
1210 if (ret < 0)
1212 fprintf (stderr, "Error setting the PSK credentials: %s\n",
1213 gnutls_strerror (ret));
1216 gnutls_psk_set_client_credentials_function (psk_cred, psk_callback);
1217 #endif
1219 #ifdef ENABLE_ANON
1220 /* ANON stuff */
1221 if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
1223 fprintf (stderr, "Anonymous authentication error\n");
1225 #endif
1229 /* Functions to manipulate sockets
1232 ssize_t
1233 socket_recv (const socket_st * socket, void *buffer, int buffer_size)
1235 int ret;
1237 if (socket->secure)
1240 ret = gnutls_record_recv (socket->session, buffer, buffer_size);
1242 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
1243 else
1246 ret = recv (socket->fd, buffer, buffer_size, 0);
1248 while (ret == -1 && errno == EINTR);
1250 return ret;
1253 ssize_t
1254 socket_send (const socket_st * socket, const void *buffer, int buffer_size)
1256 int ret;
1258 if (socket->secure)
1261 ret = gnutls_record_send (socket->session, buffer, buffer_size);
1263 while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
1264 else
1267 ret = send (socket->fd, buffer, buffer_size, 0);
1269 while (ret == -1 && errno == EINTR);
1271 if (ret > 0 && ret != buffer_size && verbose)
1272 fprintf (stderr,
1273 "*** Only sent %d bytes instead of %d.\n", ret, buffer_size);
1275 return ret;
1278 void
1279 socket_bye (socket_st * socket)
1281 int ret;
1282 if (socket->secure)
1285 ret = gnutls_bye (socket->session, GNUTLS_SHUT_RDWR);
1286 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
1287 if (ret < 0)
1288 fprintf (stderr, "*** gnutls_bye() error: %s\n",
1289 gnutls_strerror (ret));
1290 gnutls_deinit (socket->session);
1291 socket->session = NULL;
1294 freeaddrinfo (socket->addr_info);
1295 socket->addr_info = socket->ptr = NULL;
1297 free (socket->ip);
1298 free (socket->hostname);
1299 free (socket->service);
1301 shutdown (socket->fd, SHUT_RDWR); /* no more receptions */
1302 close (socket->fd);
1304 socket->fd = -1;
1305 socket->secure = 0;
1308 void
1309 socket_connect (const socket_st * hd)
1311 int err;
1313 printf ("Connecting to '%s:%s'...\n", hd->ip, hd->service);
1315 err = connect (hd->fd, hd->ptr->ai_addr, hd->ptr->ai_addrlen);
1316 if (err < 0)
1318 fprintf (stderr, "Cannot connect to %s:%s: %s\n", hd->hostname,
1319 hd->service, strerror (errno));
1320 exit (1);
1324 void
1325 socket_open (socket_st * hd, const char *hostname, const char *service)
1327 struct addrinfo hints, *res, *ptr;
1328 int sd, err;
1329 char buffer[MAX_BUF + 1];
1330 char portname[16] = { 0 };
1332 printf ("Resolving '%s'...\n", hostname);
1333 /* get server name */
1334 memset (&hints, 0, sizeof (hints));
1335 hints.ai_socktype = SOCK_STREAM;
1336 if ((err = getaddrinfo (hostname, service, &hints, &res)))
1338 fprintf (stderr, "Cannot resolve %s:%s: %s\n", hostname, service,
1339 gai_strerror (err));
1340 exit (1);
1343 sd = -1;
1344 for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
1346 sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
1347 if (sd == -1)
1348 continue;
1350 if ((err = getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF,
1351 portname, sizeof (portname),
1352 NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1354 fprintf (stderr, "getnameinfo(): %s\n", gai_strerror (err));
1355 freeaddrinfo (res);
1356 exit (1);
1359 break;
1362 if (sd == -1)
1364 fprintf (stderr, "socket(): %s\n", strerror (errno));
1365 exit (1);
1368 hd->secure = 0;
1369 hd->fd = sd;
1370 hd->hostname = strdup (hostname);
1371 hd->ip = strdup (buffer);
1372 hd->service = strdup (portname);
1373 hd->ptr = ptr;
1374 hd->addr_info = res;
1376 return;