The test now works.
[gnutls.git] / src / cli.c
blob27ab86719101a2c85f37d73c4c3aac11ce5d6fe3
1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation
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 <unistd.h>
32 #include <fcntl.h>
34 #include <gnutls/gnutls.h>
35 #include <gnutls/extra.h>
36 #include <gnutls/x509.h>
37 #include <gnutls/openpgp.h>
38 #include <gcrypt.h>
40 #include "error.h"
41 #include "read-file.h"
43 #include "common.h"
44 #include "cli-gaa.h"
46 #if defined _WIN32 || defined __WIN32__
47 int _win_select(int max_fd, fd_set * rfds, fd_set * wfds, fd_set * efds,
48 const struct timeval *tv);
49 #define select _win_select
50 #endif
52 #define SA struct sockaddr
53 #define ERR(err,s) do { if (err==-1) {perror(s);return(1);} } while (0)
54 #define MAX_BUF 4096
56 /* global stuff here */
57 int resume, starttls, insecure;
58 char *hostname = NULL;
59 char *service;
60 int record_max_size;
61 int fingerprint;
62 int crlf;
63 int verbose = 0;
64 extern int print_cert;
66 char *srp_passwd = NULL;
67 char *srp_username;
68 char *pgp_keyfile;
69 char *pgp_certfile;
70 char *pgp_keyring;
71 char *x509_keyfile;
72 char *x509_certfile;
73 char *x509_cafile;
74 char *x509_crlfile = NULL;
75 static int x509ctype;
76 static int disable_extensions;
78 char *psk_username = NULL;
79 gnutls_datum_t psk_key = { NULL, 0 };
81 static gnutls_srp_client_credentials_t srp_cred;
82 static gnutls_psk_client_credentials_t psk_cred;
83 static gnutls_anon_client_credentials_t anon_cred;
84 static gnutls_certificate_credentials_t xcred;
86 static gaainfo info;
88 static int protocol_priority[PRI_MAX];
89 static int kx_priority[PRI_MAX];
90 static int cipher_priority[PRI_MAX];
91 static int comp_priority[PRI_MAX];
92 static int mac_priority[PRI_MAX];
93 static int cert_type_priority[PRI_MAX];
95 /* end of global stuff */
97 /* prototypes */
98 typedef struct
100 int fd;
101 gnutls_session_t session;
102 int secure;
103 char *hostname;
104 char *ip;
105 char *service;
106 struct addrinfo *ptr;
107 struct addrinfo *addr_info;
108 } socket_st;
110 ssize_t socket_recv (const socket_st * socket, void *buffer, int buffer_size);
111 ssize_t socket_send (const socket_st * socket, const void *buffer,
112 int buffer_size);
113 void socket_open (socket_st * hd, const char *hostname, const char *service);
114 void socket_connect (const socket_st * hd);
115 void socket_bye (socket_st * socket);
117 static void check_rehandshake (socket_st * socket, int ret);
118 static int do_handshake (socket_st * socket);
119 static void init_global_tls_stuff (void);
122 #undef MAX
123 #define MAX(X,Y) (X >= Y ? X : Y);
126 /* Helper functions to load a certificate and key
127 * files into memory.
129 static gnutls_datum_t
130 load_file (const char *file)
132 FILE *f;
133 gnutls_datum_t loaded_file = { NULL, 0 };
134 long filelen;
135 void *ptr;
137 if (!(f = fopen (file, "r"))
138 || fseek (f, 0, SEEK_END) != 0
139 || (filelen = ftell (f)) < 0
140 || fseek (f, 0, SEEK_SET) != 0
141 || !(ptr = malloc ((size_t) filelen))
142 || fread (ptr, 1, (size_t) filelen, f) < (size_t) filelen)
144 return loaded_file;
147 loaded_file.data = ptr;
148 loaded_file.size = (unsigned int) filelen;
149 return loaded_file;
152 static void
153 unload_file (gnutls_datum_t data)
155 free (data.data);
158 #define MAX_CRT 6
159 static unsigned int x509_crt_size;
160 static gnutls_x509_crt_t x509_crt[MAX_CRT];
161 static gnutls_x509_privkey_t x509_key = NULL;
163 static gnutls_openpgp_crt_t pgp_crt = NULL;
164 static gnutls_openpgp_privkey_t pgp_key = NULL;
166 static void get_keyid( gnutls_openpgp_keyid_t keyid, const char* str)
168 size_t keyid_size = sizeof(keyid);
170 if (strlen(str) != 16)
172 fprintf(stderr, "The OpenPGP subkey ID has to be 16 hexadecimal characters.\n");
173 exit(1);
176 if (gnutls_hex2bin (str, strlen(str), keyid, &keyid_size) < 0)
178 fprintf(stderr, "Error converting hex string: %s.\n", str);
179 exit(1);
182 return;
185 /* Load the certificate and the private key.
187 static void
188 load_keys (void)
190 unsigned int crt_num;
191 int ret;
192 gnutls_datum_t data;
194 if (x509_certfile != NULL && x509_keyfile != NULL)
196 data = load_file (x509_certfile);
197 if (data.data == NULL)
199 fprintf (stderr, "*** Error loading cert file.\n");
200 exit (1);
203 crt_num = MAX_CRT;
204 ret =
205 gnutls_x509_crt_list_import (x509_crt, &crt_num, &data,
206 GNUTLS_X509_FMT_PEM,
207 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
208 if (ret < 0)
210 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
212 fprintf (stderr,
213 "*** Error loading cert file: Too many certs %d\n",
214 crt_num);
217 else
219 fprintf (stderr,
220 "*** Error loading cert file: %s\n",
221 gnutls_strerror (ret));
223 exit (1);
225 x509_crt_size = ret;
226 fprintf (stderr, "Processed %d client certificates...\n", ret);
228 unload_file (data);
230 data = load_file (x509_keyfile);
231 if (data.data == NULL)
233 fprintf (stderr, "*** Error loading key file.\n");
234 exit (1);
237 gnutls_x509_privkey_init (&x509_key);
239 ret = gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM);
240 if (ret < 0)
242 fprintf (stderr, "*** Error loading key file: %s\n",
243 gnutls_strerror (ret));
244 exit (1);
247 unload_file (data);
249 fprintf (stderr, "Processed %d client X.509 certificates...\n",
250 x509_crt_size);
252 #ifdef ENABLE_OPENPGP
253 if (pgp_certfile != NULL && pgp_keyfile != NULL)
255 data = load_file (pgp_certfile);
256 if (data.data == NULL)
258 fprintf (stderr, "*** Error loading PGP cert file.\n");
259 exit (1);
261 gnutls_openpgp_crt_init (&pgp_crt);
263 ret =
264 gnutls_openpgp_crt_import (pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64);
265 if (ret < 0)
267 fprintf (stderr,
268 "*** Error loading PGP cert file: %s\n",
269 gnutls_strerror (ret));
270 exit (1);
274 unload_file (data);
276 data = load_file (pgp_keyfile);
277 if (data.data == NULL)
279 fprintf (stderr, "*** Error loading PGP key file.\n");
280 exit (1);
283 gnutls_openpgp_privkey_init (&pgp_key);
285 ret =
286 gnutls_openpgp_privkey_import (pgp_key, &data,
287 GNUTLS_OPENPGP_FMT_BASE64, NULL, 0);
288 if (ret < 0)
290 fprintf (stderr,
291 "*** Error loading PGP key file: %s\n",
292 gnutls_strerror (ret));
293 exit (1);
296 unload_file (data);
298 if (info.pgp_subkey != NULL)
300 gnutls_openpgp_keyid_t keyid;
302 if (strcasecmp(info.pgp_subkey, "auto")==0)
304 ret = gnutls_openpgp_crt_get_auth_subkey( pgp_crt, keyid, 1);
305 if (ret < 0)
307 fprintf (stderr,
308 "*** Error setting preferred sub key id (%s): %s\n", info.pgp_subkey,
309 gnutls_strerror (ret));
310 exit (1);
313 else
314 get_keyid( keyid, info.pgp_subkey);
316 ret = gnutls_openpgp_crt_set_preferred_key_id( pgp_crt, keyid);
317 if (ret >= 0)
318 ret = gnutls_openpgp_privkey_set_preferred_key_id( pgp_key, keyid);
319 if (ret < 0)
321 fprintf (stderr,
322 "*** Error setting preferred sub key id (%s): %s\n", info.pgp_subkey,
323 gnutls_strerror (ret));
324 exit (1);
328 fprintf (stderr, "Processed 1 client PGP certificate...\n");
330 #endif
336 /* This callback should be associated with a session by calling
337 * gnutls_certificate_client_set_retrieve_function( session, cert_callback),
338 * before a handshake.
341 static int
342 cert_callback (gnutls_session_t session,
343 const gnutls_datum_t * req_ca_rdn, int nreqs,
344 const gnutls_pk_algorithm_t * sign_algos,
345 int sign_algos_length, gnutls_retr_st * st)
347 char issuer_dn[256];
348 int i, ret;
349 size_t len;
351 if (verbose)
354 /* Print the server's trusted CAs
356 if (nreqs > 0)
357 printf ("- Server's trusted authorities:\n");
358 else
359 printf ("- Server did not send us any trusted authorities names.\n");
361 /* print the names (if any) */
362 for (i = 0; i < nreqs; i++)
364 len = sizeof (issuer_dn);
365 ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len);
366 if (ret >= 0)
368 printf (" [%d]: ", i);
369 printf ("%s\n", issuer_dn);
374 /* Select a certificate and return it.
375 * The certificate must be of any of the "sign algorithms"
376 * supported by the server.
379 st->type = gnutls_certificate_type_get (session);
381 st->ncerts = 0;
383 if (st->type == GNUTLS_CRT_X509)
385 if (x509_crt != NULL && x509_key != NULL)
387 st->ncerts = x509_crt_size;
389 st->cert.x509 = x509_crt;
390 st->key.x509 = x509_key;
392 st->deinit_all = 0;
394 return 0;
397 else if (st->type == GNUTLS_CRT_OPENPGP)
399 if (pgp_key != NULL && pgp_crt != NULL)
401 st->ncerts = 1;
403 st->cert.pgp = pgp_crt;
404 st->key.pgp = pgp_key;
406 st->deinit_all = 0;
408 return 0;
412 printf ("- Successfully sent %d certificate(s) to server.\n", st->ncerts);
413 return 0;
417 /* initializes a gnutls_session_t with some defaults.
419 static gnutls_session_t
420 init_tls_session (const char *hostname)
422 const char *err;
424 gnutls_session_t session;
426 gnutls_init (&session, GNUTLS_CLIENT);
428 if (gnutls_priority_set_direct (session, info.priorities, &err) < 0)
430 fprintf(stderr, "Syntax error at: %s\n", err);
431 exit(1);
434 /* allow the use of private ciphersuites.
436 if (disable_extensions == 0)
438 gnutls_handshake_set_private_extensions (session, 1);
439 gnutls_server_name_set (session, GNUTLS_NAME_DNS, hostname,
440 strlen (hostname));
441 if (cert_type_priority[0])
442 gnutls_certificate_type_set_priority (session, cert_type_priority);
445 if (cipher_priority[0])
446 gnutls_cipher_set_priority (session, cipher_priority);
447 if (comp_priority[0])
448 gnutls_compression_set_priority (session, comp_priority);
449 if (kx_priority[0])
450 gnutls_kx_set_priority (session, kx_priority);
451 if (protocol_priority[0])
452 gnutls_protocol_set_priority (session, protocol_priority);
453 if (mac_priority[0])
454 gnutls_mac_set_priority (session, mac_priority);
456 gnutls_dh_set_prime_bits (session, 512);
458 gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred);
459 if (srp_cred)
460 gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred);
461 if (psk_cred)
462 gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred);
463 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
465 gnutls_certificate_client_set_retrieve_function (xcred, cert_callback);
467 /* send the fingerprint */
468 #ifdef ENABLE_OPENPGP
469 if (fingerprint != 0)
470 gnutls_openpgp_send_cert (session, GNUTLS_OPENPGP_CERT_FINGERPRINT);
471 #endif
473 /* use the max record size extension */
474 if (record_max_size > 0 && disable_extensions == 0)
476 if (gnutls_record_set_max_size (session, record_max_size) < 0)
478 fprintf (stderr,
479 "Cannot set the maximum record size to %d.\n",
480 record_max_size);
481 fprintf (stderr, "Possible values: 512, 1024, 2048, 4096.\n");
482 exit (1);
486 #ifdef ENABLE_OPRFI
487 if (info.opaque_prf_input)
488 gnutls_oprfi_enable_client (session, strlen (info.opaque_prf_input),
489 info.opaque_prf_input);
490 #endif
492 return session;
495 static void gaa_parser (int argc, char **argv);
497 /* Returns zero if the error code was successfully handled.
499 static int
500 handle_error (socket_st * hd, int err)
502 int alert, ret;
503 const char *err_type, *str;
505 if (err >= 0)
506 return 0;
508 if (gnutls_error_is_fatal (err) == 0)
510 ret = 0;
511 err_type = "Non fatal";
513 else
515 ret = err;
516 err_type = "Fatal";
519 str = gnutls_strerror (err);
520 if (str == NULL)
521 str = str_unknown;
522 fprintf (stderr, "*** %s error: %s\n", err_type, str);
524 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
525 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
527 alert = gnutls_alert_get (hd->session);
528 str = gnutls_alert_get_name (alert);
529 if (str == NULL)
530 str = str_unknown;
531 printf ("*** Received alert [%d]: %s\n", alert, str);
533 /* In SRP if the alert is MISSING_SRP_USERNAME,
534 * we should read the username/password and
535 * call gnutls_handshake(). This is not implemented
536 * here.
540 check_rehandshake (hd, ret);
542 return ret;
545 int starttls_alarmed = 0;
547 void
548 starttls_alarm (int signum)
550 starttls_alarmed = 1;
553 static void
554 tls_log_func (int level, const char *str)
556 fprintf (stderr, "|<%d>| %s", level, str);
560 main (int argc, char **argv)
562 int err, ret;
563 int ii, i;
564 char buffer[MAX_BUF + 1];
565 char *session_data = NULL;
566 char *session_id = NULL;
567 size_t session_data_size;
568 size_t session_id_size;
569 fd_set rset;
570 int maxfd;
571 struct timeval tv;
572 int user_term = 0;
573 socket_st hd;
575 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
577 if ((ret = gnutls_global_init ()) < 0)
579 fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
580 exit (1);
583 gaa_parser (argc, argv);
584 if (hostname == NULL)
586 fprintf (stderr, "No hostname given\n");
587 exit (1);
590 gnutls_global_set_log_function (tls_log_func);
591 gnutls_global_set_log_level (info.debug);
593 sockets_init ();
595 #ifndef _WIN32
596 signal (SIGPIPE, SIG_IGN);
597 #endif
599 init_global_tls_stuff ();
601 socket_open (&hd, hostname, service);
602 socket_connect (&hd);
604 hd.session = init_tls_session (hostname);
605 if (starttls)
606 goto after_handshake;
608 for (i = 0; i < 2; i++)
612 if (i == 1)
614 hd.session = init_tls_session (hostname);
615 gnutls_session_set_data (hd.session, session_data,
616 session_data_size);
617 free (session_data);
620 ret = do_handshake (&hd);
622 if (ret < 0)
624 fprintf (stderr, "*** Handshake has failed\n");
625 gnutls_perror (ret);
626 gnutls_deinit (hd.session);
627 return 1;
629 else
631 printf ("- Handshake was completed\n");
632 if (gnutls_session_is_resumed (hd.session) != 0)
633 printf ("*** This is a resumed session\n");
638 if (resume != 0 && i == 0)
641 gnutls_session_get_data (hd.session, NULL, &session_data_size);
642 session_data = malloc (session_data_size);
644 gnutls_session_get_data (hd.session, session_data,
645 &session_data_size);
647 gnutls_session_get_id (hd.session, NULL, &session_id_size);
648 session_id = malloc (session_id_size);
649 gnutls_session_get_id (hd.session, session_id, &session_id_size);
651 /* print some information */
652 print_info (hd.session, hostname, info.insecure);
654 printf ("- Disconnecting\n");
655 socket_bye (&hd);
657 printf
658 ("\n\n- Connecting again- trying to resume previous session\n");
659 socket_open (&hd, hostname, service);
660 socket_connect (&hd);
662 else
664 break;
668 after_handshake:
670 /* Warning! Do not touch this text string, it is used by external
671 programs to search for when gnutls-cli has reached this point. */
672 printf ("\n- Simple Client Mode:\n\n");
674 #ifndef _WIN32
675 signal (SIGALRM, &starttls_alarm);
676 #endif
678 /* do not buffer */
679 #if !(defined _WIN32 || defined __WIN32__)
680 setbuf (stdin, NULL);
681 #endif
682 setbuf (stdout, NULL);
683 setbuf (stderr, NULL);
685 for (;;)
687 if (starttls_alarmed && !hd.secure)
689 /* Warning! Do not touch this text string, it is used by
690 external programs to search for when gnutls-cli has
691 reached this point. */
692 fprintf (stderr, "*** Starting TLS handshake\n");
693 ret = do_handshake (&hd);
694 if (ret < 0)
696 fprintf (stderr, "*** Handshake has failed\n");
697 user_term = 1;
698 break;
702 FD_ZERO (&rset);
703 FD_SET (fileno (stdin), &rset);
704 FD_SET (hd.fd, &rset);
706 maxfd = MAX (fileno (stdin), hd.fd);
707 tv.tv_sec = 3;
708 tv.tv_usec = 0;
710 err = select (maxfd + 1, &rset, NULL, NULL, &tv);
711 if (err < 0)
712 continue;
714 if (FD_ISSET (hd.fd, &rset))
716 memset (buffer, 0, MAX_BUF + 1);
717 ret = socket_recv (&hd, buffer, MAX_BUF);
719 if (ret == 0)
721 printf ("- Peer has closed the GNUTLS connection\n");
722 break;
724 else if (handle_error (&hd, ret) < 0 && user_term == 0)
726 fprintf (stderr,
727 "*** Server has terminated the connection abnormally.\n");
728 break;
730 else if (ret > 0)
732 if (verbose != 0)
733 printf ("- Received[%d]: ", ret);
734 for (ii = 0; ii < ret; ii++)
736 fputc (buffer[ii], stdout);
738 fflush (stdout);
741 if (user_term != 0)
742 break;
745 if (FD_ISSET (fileno (stdin), &rset))
747 if (fgets (buffer, MAX_BUF, stdin) == NULL)
749 if (hd.secure == 0)
751 /* Warning! Do not touch this text string, it is
752 used by external programs to search for when
753 gnutls-cli has reached this point. */
754 fprintf (stderr, "*** Starting TLS handshake\n");
755 ret = do_handshake (&hd);
756 clearerr (stdin);
757 if (ret < 0)
759 fprintf (stderr, "*** Handshake has failed\n");
760 user_term = 1;
761 break;
764 else
766 user_term = 1;
767 break;
769 continue;
772 if (crlf != 0)
774 char *b = strchr (buffer, '\n');
775 if (b != NULL)
776 strcpy (b, "\r\n");
779 ret = socket_send (&hd, buffer, strlen (buffer));
781 if (ret > 0)
783 if (verbose != 0)
784 printf ("- Sent: %d bytes\n", ret);
786 else
787 handle_error (&hd, ret);
792 if (info.debug)
793 gcry_control (GCRYCTL_DUMP_RANDOM_STATS);
795 if (user_term != 0)
796 socket_bye (&hd);
797 else
798 gnutls_deinit (hd.session);
800 #ifdef ENABLE_SRP
801 if (srp_cred)
802 gnutls_srp_free_client_credentials (srp_cred);
803 #endif
804 #ifdef ENABLE_PSK
805 if (psk_cred)
806 gnutls_psk_free_client_credentials (psk_cred);
807 #endif
809 gnutls_certificate_free_credentials (xcred);
811 #ifdef ENABLE_ANON
812 gnutls_anon_free_client_credentials (anon_cred);
813 #endif
815 gnutls_global_deinit ();
817 return 0;
820 void
821 gaa_parser (int argc, char **argv)
823 if (gaa (argc, argv, &info) != -1)
825 fprintf (stderr,
826 "Error in the arguments. Use the --help or -h parameters to get more information.\n");
827 exit (1);
830 verbose = info.verbose;
831 disable_extensions = info.disable_extensions;
832 print_cert = info.print_cert;
833 starttls = info.starttls;
834 resume = info.resume;
835 insecure = info.insecure;
836 service = info.port;
837 record_max_size = info.record_size;
838 fingerprint = info.fingerprint;
840 if (info.fmtder == 0)
841 x509ctype = GNUTLS_X509_FMT_PEM;
842 else
843 x509ctype = GNUTLS_X509_FMT_DER;
845 srp_username = info.srp_username;
846 srp_passwd = info.srp_passwd;
847 x509_cafile = info.x509_cafile;
848 x509_crlfile = info.x509_crlfile;
849 x509_keyfile = info.x509_keyfile;
850 x509_certfile = info.x509_certfile;
851 pgp_keyfile = info.pgp_keyfile;
852 pgp_certfile = info.pgp_certfile;
854 psk_username = info.psk_username;
855 psk_key.data = (unsigned char *) info.psk_key;
856 if (info.psk_key != NULL)
857 psk_key.size = strlen (info.psk_key);
858 else
859 psk_key.size = 0;
861 pgp_keyring = info.pgp_keyring;
863 crlf = info.crlf;
865 if (info.rest_args == NULL)
866 hostname = "localhost";
867 else
868 hostname = info.rest_args;
870 parse_protocols (info.proto, info.nproto, protocol_priority);
871 parse_ciphers (info.ciphers, info.nciphers, cipher_priority);
872 parse_macs (info.macs, info.nmacs, mac_priority);
873 parse_ctypes (info.ctype, info.nctype, cert_type_priority);
874 parse_kx (info.kx, info.nkx, kx_priority);
875 parse_comp (info.comp, info.ncomp, comp_priority);
878 void
879 cli_version (void)
881 const char *v = gnutls_check_version (NULL);
883 printf ("gnutls-cli (GnuTLS) %s\n", LIBGNUTLS_VERSION);
884 if (strcmp (v, LIBGNUTLS_VERSION) != 0)
885 printf ("libgnutls %s\n", v);
889 static void
890 check_rehandshake (socket_st * socket, int ret)
892 if (socket->secure && ret == GNUTLS_E_REHANDSHAKE)
894 /* There is a race condition here. If application
895 * data is sent after the rehandshake request,
896 * the server thinks we ignored his request.
897 * This is a bad design of this client.
899 printf ("*** Received rehandshake request\n");
900 /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
902 ret = do_handshake (socket);
904 if (ret == 0)
906 printf ("*** Rehandshake was performed.\n");
908 else
910 printf ("*** Rehandshake Failed.\n");
916 static int
917 do_handshake (socket_st * socket)
919 int ret;
920 gnutls_transport_set_ptr (socket->session,
921 (gnutls_transport_ptr_t) socket->fd);
924 ret = gnutls_handshake (socket->session);
926 if (ret < 0)
928 handle_error (socket, ret);
931 while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
933 if (ret == 0)
935 /* print some information */
936 print_info (socket->session, socket->hostname, info.insecure);
938 if ((x509_cafile || pgp_keyring) && !insecure)
940 int rc;
941 unsigned int status;
943 /* abort if verification fail */
944 rc = gnutls_certificate_verify_peers2 (socket->session, &status);
945 if (rc != 0 || status != 0)
947 printf ("*** Verifying server certificate failed...\n");
948 exit (1);
952 socket->secure = 1;
955 return ret;
958 static int
959 srp_username_callback (gnutls_session_t session,
960 char **username, char **password)
962 if (srp_username == NULL || srp_passwd == NULL)
964 return -1;
967 *username = gnutls_strdup (srp_username);
968 *password = gnutls_strdup (srp_passwd);
970 return 0;
973 static int psk_callback (gnutls_session_t session,
974 char **username,
975 gnutls_datum_t * key)
977 const char *hint = gnutls_psk_client_get_hint (session);
978 char *passwd;
979 int ret;
981 printf ("- PSK client callback. ");
982 if (hint)
983 printf ("PSK hint '%s'\n", hint);
984 else
985 printf ("No PSK hint\n");
987 if (info.psk_username)
988 *username = gnutls_strdup (info.psk_username);
989 else
991 char *tmp = NULL;
992 ssize_t n, len;
994 printf ("Enter PSK identity: ");
995 fflush (stdout);
996 len = getline (&tmp, &n, stdin);
998 if (tmp == NULL)
1000 fprintf (stderr, "No username given, aborting...\n");
1001 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1004 if (tmp[strlen (tmp) - 1] == '\n')
1005 tmp[strlen (tmp) - 1] = '\0';
1006 if (tmp[strlen (tmp) - 1] == '\r')
1007 tmp[strlen (tmp) - 1] = '\0';
1009 *username = gnutls_strdup (tmp);
1010 free (tmp);
1012 if (!*username)
1013 return GNUTLS_E_MEMORY_ERROR;
1015 passwd = getpass ("Enter password: ");
1016 if (passwd == NULL)
1018 fprintf (stderr, "No password given, aborting...\n");
1019 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1022 ret = gnutls_psk_netconf_derive_key (passwd,
1023 *username,
1024 hint ? hint : "",
1025 key);
1026 if (ret < 0)
1028 fprintf (stderr, "Error deriving password: %s\n", gnutls_strerror (ret));
1029 gnutls_free (*username);
1030 return ret;
1033 if (info.debug)
1035 char hexkey[41];
1036 size_t res_size = sizeof (hexkey);
1037 gnutls_hex_encode (key, hexkey, &res_size);
1038 fprintf (stderr, "PSK username: %s\n", *username);
1039 fprintf (stderr, "PSK hint: %s\n", hint);
1040 fprintf (stderr, "PSK key: %s\n", hexkey);
1043 return 0;
1046 static void
1047 init_global_tls_stuff (void)
1049 int ret;
1051 /* X509 stuff */
1052 if (gnutls_certificate_allocate_credentials (&xcred) < 0)
1054 fprintf (stderr, "Certificate allocation memory error\n");
1055 exit (1);
1058 /* there are some CAs that have a v1 certificate *%&@#*%&
1060 gnutls_certificate_set_verify_flags (xcred,
1061 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
1063 if (x509_cafile != NULL)
1065 ret =
1066 gnutls_certificate_set_x509_trust_file (xcred,
1067 x509_cafile, x509ctype);
1068 if (ret < 0)
1070 fprintf (stderr, "Error setting the x509 trust file\n");
1072 else
1074 printf ("Processed %d CA certificate(s).\n", ret);
1077 #ifdef ENABLE_PKI
1078 if (x509_crlfile != NULL)
1080 ret =
1081 gnutls_certificate_set_x509_crl_file (xcred, x509_crlfile, x509ctype);
1082 if (ret < 0)
1084 fprintf (stderr, "Error setting the x509 CRL file\n");
1086 else
1088 printf ("Processed %d CRL(s).\n", ret);
1091 #endif
1093 load_keys ();
1095 #ifdef ENABLE_OPENPGP
1096 if (pgp_keyring != NULL)
1098 ret = gnutls_certificate_set_openpgp_keyring_file (xcred, pgp_keyring, GNUTLS_OPENPGP_FMT_BASE64);
1099 if (ret < 0)
1101 fprintf (stderr, "Error setting the OpenPGP keyring file\n");
1104 #endif
1106 #ifdef ENABLE_SRP
1107 if (srp_username && srp_passwd)
1109 /* SRP stuff */
1110 if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0)
1112 fprintf (stderr, "SRP authentication error\n");
1115 gnutls_srp_set_client_credentials_function (srp_cred,
1116 srp_username_callback);
1118 #endif
1120 #ifdef ENABLE_PSK
1121 /* PSK stuff */
1122 if (gnutls_psk_allocate_client_credentials (&psk_cred) < 0)
1124 fprintf (stderr, "PSK authentication error\n");
1127 if (psk_username && psk_key.data)
1129 ret = gnutls_psk_set_client_credentials (psk_cred,
1130 psk_username, &psk_key,
1131 GNUTLS_PSK_KEY_HEX);
1132 if (ret < 0)
1134 fprintf (stderr, "Error setting the PSK credentials: %s\n",
1135 gnutls_strerror (ret));
1138 gnutls_psk_set_client_credentials_function (psk_cred, psk_callback);
1139 #endif
1141 #ifdef ENABLE_ANON
1142 /* ANON stuff */
1143 if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
1145 fprintf (stderr, "Anonymous authentication error\n");
1147 #endif
1151 /* Functions to manipulate sockets
1154 ssize_t
1155 socket_recv (const socket_st * socket, void *buffer, int buffer_size)
1157 int ret;
1159 if (socket->secure)
1162 ret = gnutls_record_recv (socket->session, buffer, buffer_size);
1164 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
1165 else
1168 ret = recv (socket->fd, buffer, buffer_size, 0);
1170 while (ret == -1 && errno == EINTR);
1172 return ret;
1175 ssize_t
1176 socket_send (const socket_st * socket, const void *buffer, int buffer_size)
1178 int ret;
1180 if (socket->secure)
1183 ret = gnutls_record_send (socket->session, buffer, buffer_size);
1185 while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
1186 else
1189 ret = send (socket->fd, buffer, buffer_size, 0);
1191 while (ret == -1 && errno == EINTR);
1193 if (ret > 0 && ret != buffer_size && verbose)
1194 fprintf (stderr,
1195 "*** Only sent %d bytes instead of %d.\n", ret, buffer_size);
1197 return ret;
1200 void
1201 socket_bye (socket_st * socket)
1203 int ret;
1204 if (socket->secure)
1207 ret = gnutls_bye (socket->session, GNUTLS_SHUT_RDWR);
1208 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
1209 if (ret < 0)
1210 fprintf (stderr, "*** gnutls_bye() error: %s\n",
1211 gnutls_strerror (ret));
1212 gnutls_deinit (socket->session);
1213 socket->session = NULL;
1216 freeaddrinfo (socket->addr_info);
1217 socket->addr_info = socket->ptr = NULL;
1219 free (socket->ip);
1220 free (socket->hostname);
1221 free (socket->service);
1223 shutdown (socket->fd, SHUT_RDWR); /* no more receptions */
1224 close (socket->fd);
1226 socket->fd = -1;
1227 socket->secure = 0;
1230 void
1231 socket_connect (const socket_st * hd)
1233 int err;
1235 printf ("Connecting to '%s:%s'...\n", hd->ip, hd->service);
1237 err = connect (hd->fd, hd->ptr->ai_addr, hd->ptr->ai_addrlen);
1238 if (err < 0)
1240 fprintf (stderr, "Cannot connect to %s:%s: %s\n", hd->hostname,
1241 hd->service, strerror (errno));
1242 exit (1);
1246 void
1247 socket_open (socket_st * hd, const char *hostname, const char *service)
1249 struct addrinfo hints, *res, *ptr;
1250 int sd, err;
1251 char buffer[MAX_BUF + 1];
1252 char portname[16] = { 0 };
1254 printf ("Resolving '%s'...\n", hostname);
1255 /* get server name */
1256 memset (&hints, 0, sizeof (hints));
1257 hints.ai_socktype = SOCK_STREAM;
1258 if ((err = getaddrinfo (hostname, service, &hints, &res)))
1260 fprintf (stderr, "Cannot resolve %s:%s: %s\n", hostname, service,
1261 gai_strerror (err));
1262 exit (1);
1265 sd = -1;
1266 for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
1268 sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
1269 if (sd == -1)
1270 continue;
1272 if ((err = getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF,
1273 portname, sizeof (portname),
1274 NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1276 fprintf (stderr, "getnameinfo(): %s\n", gai_strerror (err));
1277 freeaddrinfo (res);
1278 exit (1);
1281 break;
1284 if (sd == -1)
1286 fprintf (stderr, "socket(): %s\n", strerror (errno));
1287 exit (1);
1290 hd->secure = 0;
1291 hd->fd = sd;
1292 hd->hostname = strdup (hostname);
1293 hd->ip = strdup (buffer);
1294 hd->service = strdup (portname);
1295 hd->ptr = ptr;
1296 hd->addr_info = res;
1298 return;