minor update to the fix.
[gnutls.git] / src / cli.c
blob0d3cbde5122f4d07d5e491ced43058bf2334df83
1 /*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3 * 2009, 2010 Free Software Foundation, Inc.
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 <gnutls/pkcs11.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 /* end of global stuff */
89 /* prototypes */
90 typedef struct
92 int fd;
93 gnutls_session_t session;
94 int secure;
95 char *hostname;
96 char *ip;
97 char *service;
98 struct addrinfo *ptr;
99 struct addrinfo *addr_info;
100 } socket_st;
102 ssize_t socket_recv (const socket_st * socket, void *buffer, int buffer_size);
103 ssize_t socket_send (const socket_st * socket, const void *buffer,
104 int buffer_size);
105 void socket_open (socket_st * hd, const char *hostname, const char *service);
106 void socket_connect (const socket_st * hd);
107 void socket_bye (socket_st * socket);
109 static void check_rehandshake (socket_st * socket, int ret);
110 static int do_handshake (socket_st * socket);
111 static void init_global_tls_stuff (void);
113 /* Helper functions to load a certificate and key
114 * files into memory.
116 static gnutls_datum_t
117 load_file (const char *file)
119 gnutls_datum_t loaded_file = { NULL, 0 };
120 size_t length;
122 loaded_file.data = read_binary_file (file, &length);
123 if (loaded_file.data)
124 loaded_file.size = (unsigned int) length;
126 return loaded_file;
129 static void
130 unload_file (gnutls_datum_t data)
132 free (data.data);
135 #define MAX_CRT 6
136 static unsigned int x509_crt_size;
137 static gnutls_x509_crt_t x509_crt[MAX_CRT];
138 static gnutls_x509_privkey_t x509_key = NULL;
140 static gnutls_pkcs11_privkey_t pkcs11_key = NULL;
142 static gnutls_openpgp_crt_t pgp_crt = NULL;
143 static gnutls_openpgp_privkey_t pgp_key = NULL;
145 static void
146 get_keyid (gnutls_openpgp_keyid_t keyid, const char *str)
148 size_t keyid_size = sizeof (keyid);
150 if (strlen (str) != 16)
152 fprintf (stderr,
153 "The OpenPGP subkey ID has to be 16 hexadecimal characters.\n");
154 exit (1);
157 if (gnutls_hex2bin (str, strlen (str), keyid, &keyid_size) < 0)
159 fprintf (stderr, "Error converting hex string: %s.\n", str);
160 exit (1);
163 return;
166 /* Load the certificate and the private key.
168 static void
169 load_keys (void)
171 unsigned int crt_num;
172 int ret;
173 gnutls_datum_t data = { NULL, 0 };
175 if (x509_certfile != NULL && x509_keyfile != NULL)
177 #ifdef ENABLE_PKCS11
178 if (strncmp (x509_certfile, "pkcs11:", 7) == 0)
180 crt_num = 1;
181 gnutls_x509_crt_init (&x509_crt[0]);
183 ret =
184 gnutls_x509_crt_import_pkcs11_url (x509_crt[0], x509_certfile, 0);
186 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
187 ret =
188 gnutls_x509_crt_import_pkcs11_url (x509_crt[0], x509_certfile,
189 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
191 if (ret < 0)
193 fprintf (stderr, "*** Error loading cert file.\n");
194 exit (1);
196 x509_crt_size = 1;
198 else
199 #endif /* ENABLE_PKCS11 */
202 data = load_file (x509_certfile);
203 if (data.data == NULL)
205 fprintf (stderr, "*** Error loading cert file.\n");
206 exit (1);
209 crt_num = MAX_CRT;
210 ret =
211 gnutls_x509_crt_list_import (x509_crt, &crt_num, &data,
212 GNUTLS_X509_FMT_PEM,
213 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
214 if (ret < 0)
216 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
218 fprintf (stderr,
219 "*** Error loading cert file: Too many certs %d\n",
220 crt_num);
223 else
225 fprintf (stderr,
226 "*** Error loading cert file: %s\n",
227 gnutls_strerror (ret));
229 exit (1);
231 x509_crt_size = ret;
233 fprintf (stderr, "Processed %d client certificates...\n", ret);
235 unload_file (data);
237 #ifdef ENABLE_PKCS11
238 if (strncmp (x509_keyfile, "pkcs11:", 7) == 0)
240 gnutls_pkcs11_privkey_init (&pkcs11_key);
242 ret =
243 gnutls_pkcs11_privkey_import_url (pkcs11_key, x509_keyfile, 0);
244 if (ret < 0)
246 fprintf (stderr, "*** Error loading url: %s\n",
247 gnutls_strerror (ret));
248 exit (1);
251 else
252 #endif /* ENABLE_PKCS11 */
254 data = load_file (x509_keyfile);
255 if (data.data == NULL)
257 fprintf (stderr, "*** Error loading key file.\n");
258 exit (1);
261 gnutls_x509_privkey_init (&x509_key);
263 ret =
264 gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM);
265 if (ret < 0)
267 fprintf (stderr, "*** Error loading key file: %s\n",
268 gnutls_strerror (ret));
269 exit (1);
272 unload_file (data);
275 fprintf (stderr, "Processed %d client X.509 certificates...\n",
276 x509_crt_size);
278 #ifdef ENABLE_OPENPGP
279 if (pgp_certfile != NULL && pgp_keyfile != NULL)
281 data = load_file (pgp_certfile);
282 if (data.data == NULL)
284 fprintf (stderr, "*** Error loading PGP cert file.\n");
285 exit (1);
287 gnutls_openpgp_crt_init (&pgp_crt);
289 ret =
290 gnutls_openpgp_crt_import (pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64);
291 if (ret < 0)
293 fprintf (stderr,
294 "*** Error loading PGP cert file: %s\n",
295 gnutls_strerror (ret));
296 exit (1);
300 unload_file (data);
302 #ifdef ENABLE_PKCS11
303 if (strncmp (pgp_keyfile, "pkcs11:", 7) == 0)
305 gnutls_pkcs11_privkey_init (&pkcs11_key);
307 ret = gnutls_pkcs11_privkey_import_url (pkcs11_key, pgp_keyfile, 0);
308 if (ret < 0)
310 fprintf (stderr, "*** Error loading url: %s\n",
311 gnutls_strerror (ret));
312 exit (1);
315 else
316 #endif /* ENABLE_PKCS11 */
319 data = load_file (pgp_keyfile);
320 if (data.data == NULL)
322 fprintf (stderr, "*** Error loading PGP key file.\n");
323 exit (1);
326 gnutls_openpgp_privkey_init (&pgp_key);
328 ret =
329 gnutls_openpgp_privkey_import (pgp_key, &data,
330 GNUTLS_OPENPGP_FMT_BASE64, NULL,
332 if (ret < 0)
334 fprintf (stderr,
335 "*** Error loading PGP key file: %s\n",
336 gnutls_strerror (ret));
337 exit (1);
340 unload_file (data);
343 if (info.pgp_subkey != NULL)
345 unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE];
347 if (strcasecmp (info.pgp_subkey, "auto") == 0)
349 ret = gnutls_openpgp_crt_get_auth_subkey (pgp_crt, keyid, 1);
350 if (ret < 0)
352 fprintf (stderr,
353 "*** Error setting preferred sub key id (%s): %s\n",
354 info.pgp_subkey, gnutls_strerror (ret));
355 exit (1);
358 else
359 get_keyid (keyid, info.pgp_subkey);
361 ret = gnutls_openpgp_crt_set_preferred_key_id (pgp_crt, keyid);
362 if (ret >= 0)
363 ret =
364 gnutls_openpgp_privkey_set_preferred_key_id (pgp_key, keyid);
365 if (ret < 0)
367 fprintf (stderr,
368 "*** Error setting preferred sub key id (%s): %s\n",
369 info.pgp_subkey, gnutls_strerror (ret));
370 exit (1);
374 fprintf (stderr, "Processed 1 client PGP certificate...\n");
376 #endif
380 static int
381 cert_verify_callback (gnutls_session_t session)
383 int rc;
384 unsigned int status;
386 if (!x509_cafile && !pgp_keyring)
387 return 0;
389 rc = gnutls_certificate_verify_peers2 (session, &status);
390 if (rc != 0 || status != 0)
392 printf ("*** Verifying server certificate failed...\n");
393 if (!insecure)
394 return -1;
397 return 0;
400 /* This callback should be associated with a session by calling
401 * gnutls_certificate_client_set_retrieve_function( session, cert_callback),
402 * before a handshake.
405 static int
406 cert_callback (gnutls_session_t session,
407 const gnutls_datum_t * req_ca_rdn, int nreqs,
408 const gnutls_pk_algorithm_t * sign_algos,
409 int sign_algos_length, gnutls_retr2_st * st)
411 char issuer_dn[256];
412 int i, ret;
413 size_t len;
415 if (verbose)
417 /* Print the server's trusted CAs
419 if (nreqs > 0)
420 printf ("- Server's trusted authorities:\n");
421 else
422 printf ("- Server did not send us any trusted authorities names.\n");
424 /* print the names (if any) */
425 for (i = 0; i < nreqs; i++)
427 len = sizeof (issuer_dn);
428 ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len);
429 if (ret >= 0)
431 printf (" [%d]: ", i);
432 printf ("%s\n", issuer_dn);
437 /* Select a certificate and return it.
438 * The certificate must be of any of the "sign algorithms"
439 * supported by the server.
442 st->cert_type = gnutls_certificate_type_get (session);
444 st->ncerts = 0;
446 if (st->cert_type == GNUTLS_CRT_X509)
448 gnutls_sign_algorithm_t cert_algo, req_algo;
449 int i, match = 0;
451 if (x509_crt_size > 0)
453 ret = gnutls_x509_crt_get_signature_algorithm (x509_crt[0]);
454 if (ret < 0)
456 /* error reading signature algorithm */
457 return -1;
459 cert_algo = ret;
461 i = 0;
464 ret =
465 gnutls_sign_algorithm_get_requested (session, i, &req_algo);
466 if (ret >= 0 && cert_algo == req_algo)
468 match = 1;
469 break;
472 /* server has not requested anything specific */
473 if (i == 0 && ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
475 match = 1;
476 break;
478 i++;
480 while (ret >= 0);
482 if (match == 0)
484 printf
485 ("- Could not find a suitable certificate to send to server\n");
486 return -1;
489 if (x509_key != NULL)
491 st->key.x509 = x509_key;
492 st->key_type = GNUTLS_PRIVKEY_X509;
494 else if (pkcs11_key != NULL)
496 st->key.pkcs11 = pkcs11_key;
497 st->key_type = GNUTLS_PRIVKEY_PKCS11;
499 else
501 printf ("- Could not find a suitable key to send to server\n");
502 return -1;
505 st->ncerts = x509_crt_size;
507 st->cert.x509 = x509_crt;
509 st->deinit_all = 0;
511 return 0;
515 else if (st->cert_type == GNUTLS_CRT_OPENPGP)
517 if (pgp_crt != NULL)
520 if (pgp_key != NULL)
522 st->key.pgp = pgp_key;
523 st->key_type = GNUTLS_PRIVKEY_OPENPGP;
525 else if (pkcs11_key != NULL)
527 st->key.pkcs11 = pkcs11_key;
528 st->key_type = GNUTLS_PRIVKEY_PKCS11;
530 else
532 printf ("- Could not find a suitable key to send to server\n");
533 return -1;
536 st->ncerts = 1;
538 st->cert.pgp = pgp_crt;
540 st->deinit_all = 0;
542 return 0;
546 printf ("- Successfully sent %d certificate(s) to server.\n", st->ncerts);
547 return 0;
551 /* initializes a gnutls_session_t with some defaults.
553 static gnutls_session_t
554 init_tls_session (const char *hostname)
556 const char *err;
558 gnutls_session_t session;
560 gnutls_init (&session, GNUTLS_CLIENT);
562 if (gnutls_priority_set_direct (session, info.priorities, &err) < 0)
564 fprintf (stderr, "Syntax error at: %s\n", err);
565 exit (1);
568 /* allow the use of private ciphersuites.
570 if (disable_extensions == 0)
572 gnutls_handshake_set_private_extensions (session, 1);
573 gnutls_server_name_set (session, GNUTLS_NAME_DNS, hostname,
574 strlen (hostname));
577 gnutls_dh_set_prime_bits (session, 512);
579 gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred);
580 if (srp_cred)
581 gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred);
582 if (psk_cred)
583 gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred);
584 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
586 gnutls_certificate_set_retrieve_function (xcred, cert_callback);
587 gnutls_certificate_set_verify_function (xcred, cert_verify_callback);
588 gnutls_certificate_set_verify_flags (xcred, 0);
590 /* send the fingerprint */
591 #ifdef ENABLE_OPENPGP
592 if (fingerprint != 0)
593 gnutls_openpgp_send_cert (session, GNUTLS_OPENPGP_CERT_FINGERPRINT);
594 #endif
596 /* use the max record size extension */
597 if (record_max_size > 0 && disable_extensions == 0)
599 if (gnutls_record_set_max_size (session, record_max_size) < 0)
601 fprintf (stderr,
602 "Cannot set the maximum record size to %d.\n",
603 record_max_size);
604 fprintf (stderr, "Possible values: 512, 1024, 2048, 4096.\n");
605 exit (1);
609 #ifdef ENABLE_SESSION_TICKET
610 if (disable_extensions == 0 && !info.noticket)
611 gnutls_session_ticket_enable_client (session);
612 #endif
614 return session;
617 static void gaa_parser (int argc, char **argv);
619 /* Returns zero if the error code was successfully handled.
621 static int
622 handle_error (socket_st * hd, int err)
624 int alert, ret;
625 const char *err_type, *str;
627 if (err >= 0)
628 return 0;
630 if (gnutls_error_is_fatal (err) == 0)
632 ret = 0;
633 err_type = "Non fatal";
635 else
637 ret = err;
638 err_type = "Fatal";
641 str = gnutls_strerror (err);
642 if (str == NULL)
643 str = str_unknown;
644 fprintf (stderr, "*** %s error: %s\n", err_type, str);
646 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
647 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
649 alert = gnutls_alert_get (hd->session);
650 str = gnutls_alert_get_name (alert);
651 if (str == NULL)
652 str = str_unknown;
653 printf ("*** Received alert [%d]: %s\n", alert, str);
655 /* In SRP if the alert is MISSING_SRP_USERNAME,
656 * we should read the username/password and
657 * call gnutls_handshake(). This is not implemented
658 * here.
662 check_rehandshake (hd, err);
664 return ret;
667 int starttls_alarmed = 0;
669 #ifndef _WIN32
670 static void
671 starttls_alarm (int signum)
673 starttls_alarmed = 1;
675 #endif
677 static void
678 tls_log_func (int level, const char *str)
680 fprintf (stderr, "|<%d>| %s", level, str);
683 #define IN_KEYBOARD 1
684 #define IN_NET 2
685 #define IN_NONE 0
686 /* returns IN_KEYBOARD for keyboard input and IN_NET for network input
688 static int check_net_or_keyboard_input(socket_st* hd)
690 int maxfd;
691 fd_set rset;
692 int err;
693 struct timeval tv;
697 FD_ZERO (&rset);
698 FD_SET (fileno (stdin), &rset);
699 FD_SET (hd->fd, &rset);
701 maxfd = MAX (fileno (stdin), hd->fd);
702 tv.tv_sec = 0;
703 tv.tv_usec = 500 * 1000;
705 if (hd->secure == 1)
706 if (gnutls_record_check_pending(hd->session))
707 return IN_NET;
709 err = select (maxfd + 1, &rset, NULL, NULL, &tv);
710 if (err < 0)
711 continue;
713 if (FD_ISSET (hd->fd, &rset))
714 return IN_NET;
717 if (FD_ISSET (fileno (stdin), &rset))
718 return IN_KEYBOARD;
720 while(err == 0);
722 return IN_NONE;
726 main (int argc, char **argv)
728 int ret;
729 int ii, i, inp;
730 char buffer[MAX_BUF + 1];
731 char *session_data = NULL;
732 char *session_id = NULL;
733 size_t session_data_size;
734 size_t session_id_size = 0;
735 int user_term = 0, retval = 0;
736 socket_st hd;
737 ssize_t bytes;
739 set_program_name (argv[0]);
741 if ((ret = gnutls_global_init ()) < 0)
743 fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
744 exit (1);
747 if ((ret = gnutls_global_init_extra ()) < 0)
749 fprintf (stderr, "global_init_extra: %s\n", gnutls_strerror (ret));
750 exit (1);
753 #ifdef ENABLE_PKCS11
754 pkcs11_common ();
755 #endif
756 gaa_parser (argc, argv);
757 if (hostname == NULL)
759 fprintf (stderr, "No hostname given\n");
760 exit (1);
763 gnutls_global_set_log_function (tls_log_func);
764 gnutls_global_set_log_level (info.debug);
766 sockets_init ();
768 #ifndef _WIN32
769 signal (SIGPIPE, SIG_IGN);
770 #endif
772 init_global_tls_stuff ();
774 socket_open (&hd, hostname, service);
775 socket_connect (&hd);
777 hd.session = init_tls_session (hostname);
778 if (starttls)
779 goto after_handshake;
781 for (i = 0; i < 2; i++)
785 if (i == 1)
787 hd.session = init_tls_session (hostname);
788 gnutls_session_set_data (hd.session, session_data,
789 session_data_size);
790 free (session_data);
793 ret = do_handshake (&hd);
795 if (ret < 0)
797 fprintf (stderr, "*** Handshake has failed\n");
798 gnutls_perror (ret);
799 gnutls_deinit (hd.session);
800 return 1;
802 else
804 printf ("- Handshake was completed\n");
805 if (gnutls_session_is_resumed (hd.session) != 0)
806 printf ("*** This is a resumed session\n");
809 if (resume != 0 && i == 0)
812 gnutls_session_get_data (hd.session, NULL, &session_data_size);
813 session_data = malloc (session_data_size);
815 gnutls_session_get_data (hd.session, session_data,
816 &session_data_size);
818 gnutls_session_get_id (hd.session, NULL, &session_id_size);
820 session_id = malloc (session_id_size);
821 gnutls_session_get_id (hd.session, session_id, &session_id_size);
823 /* print some information */
824 print_info (hd.session, hostname, info.insecure);
826 printf ("- Disconnecting\n");
827 socket_bye (&hd);
829 printf
830 ("\n\n- Connecting again- trying to resume previous session\n");
831 socket_open (&hd, hostname, service);
832 socket_connect (&hd);
834 else
836 break;
840 after_handshake:
842 /* Warning! Do not touch this text string, it is used by external
843 programs to search for when gnutls-cli has reached this point. */
844 printf ("\n- Simple Client Mode:\n\n");
846 if (rehandshake)
848 ret = do_handshake (&hd);
850 if (ret < 0)
852 fprintf (stderr, "*** ReHandshake has failed\n");
853 gnutls_perror (ret);
854 gnutls_deinit (hd.session);
855 return 1;
857 else
859 printf ("- ReHandshake was completed\n");
863 #ifndef _WIN32
864 signal (SIGALRM, &starttls_alarm);
865 #endif
867 fflush (stdout);
868 fflush (stderr);
870 /* do not buffer */
871 #if !(defined _WIN32 || defined __WIN32__)
872 setbuf (stdin, NULL);
873 #endif
874 setbuf (stdout, NULL);
875 setbuf (stderr, NULL);
877 for (;;)
879 if (starttls_alarmed && !hd.secure)
881 /* Warning! Do not touch this text string, it is used by
882 external programs to search for when gnutls-cli has
883 reached this point. */
884 fprintf (stderr, "*** Starting TLS handshake\n");
885 ret = do_handshake (&hd);
886 if (ret < 0)
888 fprintf (stderr, "*** Handshake has failed\n");
889 user_term = 1;
890 retval = 1;
891 break;
895 inp = check_net_or_keyboard_input(&hd);
897 if (inp == IN_NET)
899 memset (buffer, 0, MAX_BUF + 1);
900 ret = socket_recv (&hd, buffer, MAX_BUF);
902 if (ret == 0)
904 printf ("- Peer has closed the GnuTLS connection\n");
905 break;
907 else if (handle_error (&hd, ret) < 0 && user_term == 0)
909 fprintf (stderr,
910 "*** Server has terminated the connection abnormally.\n");
911 retval = 1;
912 break;
914 else if (ret > 0)
916 if (verbose != 0)
917 printf ("- Received[%d]: ", ret);
918 for (ii = 0; ii < ret; ii++)
920 fputc (buffer[ii], stdout);
922 fflush (stdout);
925 if (user_term != 0)
926 break;
929 if (inp == IN_KEYBOARD)
931 if ((bytes = read (fileno (stdin), buffer, MAX_BUF - 1)) <= 0)
933 if (hd.secure == 0)
935 /* Warning! Do not touch this text string, it is
936 used by external programs to search for when
937 gnutls-cli has reached this point. */
938 fprintf (stderr, "*** Starting TLS handshake\n");
939 ret = do_handshake (&hd);
940 clearerr (stdin);
941 if (ret < 0)
943 fprintf (stderr, "*** Handshake has failed\n");
944 user_term = 1;
945 retval = 1;
946 break;
949 else
951 user_term = 1;
952 break;
954 continue;
957 buffer[bytes] = 0;
958 if (crlf != 0)
960 char *b = strchr (buffer, '\n');
961 if (b != NULL)
963 strcpy (b, "\r\n");
964 bytes++;
968 ret = socket_send (&hd, buffer, bytes);
970 if (ret > 0)
972 if (verbose != 0)
973 printf ("- Sent: %d bytes\n", ret);
975 else
976 handle_error (&hd, ret);
981 if (user_term != 0)
982 socket_bye (&hd);
983 else
984 gnutls_deinit (hd.session);
986 #ifdef ENABLE_SRP
987 if (srp_cred)
988 gnutls_srp_free_client_credentials (srp_cred);
989 #endif
990 #ifdef ENABLE_PSK
991 if (psk_cred)
992 gnutls_psk_free_client_credentials (psk_cred);
993 #endif
995 gnutls_certificate_free_credentials (xcred);
997 #ifdef ENABLE_ANON
998 gnutls_anon_free_client_credentials (anon_cred);
999 #endif
1001 gnutls_global_deinit ();
1003 return retval;
1006 void
1007 gaa_parser (int argc, char **argv)
1009 if (gaa (argc, argv, &info) != -1)
1011 fprintf (stderr,
1012 "Error in the arguments. Use the --help or -h parameters to get more information.\n");
1013 exit (1);
1016 verbose = info.verbose;
1017 disable_extensions = info.disable_extensions;
1018 print_cert = info.print_cert;
1019 starttls = info.starttls;
1020 resume = info.resume;
1021 rehandshake = info.rehandshake;
1022 insecure = info.insecure;
1023 service = info.port;
1024 record_max_size = info.record_size;
1025 fingerprint = info.fingerprint;
1027 if (info.fmtder == 0)
1028 x509ctype = GNUTLS_X509_FMT_PEM;
1029 else
1030 x509ctype = GNUTLS_X509_FMT_DER;
1032 srp_username = info.srp_username;
1033 srp_passwd = info.srp_passwd;
1034 x509_cafile = info.x509_cafile;
1035 x509_crlfile = info.x509_crlfile;
1036 x509_keyfile = info.x509_keyfile;
1037 x509_certfile = info.x509_certfile;
1038 pgp_keyfile = info.pgp_keyfile;
1039 pgp_certfile = info.pgp_certfile;
1041 psk_username = info.psk_username;
1042 psk_key.data = (unsigned char *) info.psk_key;
1043 if (info.psk_key != NULL)
1044 psk_key.size = strlen (info.psk_key);
1045 else
1046 psk_key.size = 0;
1048 pgp_keyring = info.pgp_keyring;
1050 crlf = info.crlf;
1052 if (info.rest_args == NULL)
1053 hostname = "localhost";
1054 else
1055 hostname = info.rest_args;
1058 void cli_version (void);
1060 void
1061 cli_version (void)
1063 const char *p = PACKAGE_NAME;
1064 if (strcmp (gnutls_check_version (NULL), PACKAGE_VERSION) != 0)
1065 p = PACKAGE_STRING;
1066 version_etc (stdout, program_name, p, gnutls_check_version (NULL),
1067 "Nikos Mavrogiannopoulos", (char *) NULL);
1071 static void
1072 check_rehandshake (socket_st * socket, int ret)
1074 if (socket->secure && ret == GNUTLS_E_REHANDSHAKE)
1076 /* There is a race condition here. If application
1077 * data is sent after the rehandshake request,
1078 * the server thinks we ignored his request.
1079 * This is a bad design of this client.
1081 printf ("*** Received rehandshake request\n");
1082 /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
1084 ret = do_handshake (socket);
1086 if (ret == 0)
1088 printf ("*** Rehandshake was performed.\n");
1090 else
1092 printf ("*** Rehandshake Failed.\n");
1098 static int
1099 do_handshake (socket_st * socket)
1101 int ret;
1103 gnutls_transport_set_ptr (socket->session,
1104 (gnutls_transport_ptr_t)
1105 gl_fd_to_handle (socket->fd));
1108 ret = gnutls_handshake (socket->session);
1110 if (ret < 0)
1112 handle_error (socket, ret);
1115 while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
1117 if (ret == 0)
1119 /* print some information */
1120 print_info (socket->session, socket->hostname, info.insecure);
1123 socket->secure = 1;
1126 else
1128 gnutls_alert_send_appropriate (socket->session, ret);
1129 shutdown (socket->fd, SHUT_RDWR);
1131 return ret;
1134 static int
1135 srp_username_callback (gnutls_session_t session,
1136 char **username, char **password)
1138 if (srp_username == NULL || srp_passwd == NULL)
1140 return -1;
1143 *username = gnutls_strdup (srp_username);
1144 *password = gnutls_strdup (srp_passwd);
1146 return 0;
1149 static int
1150 psk_callback (gnutls_session_t session, char **username, gnutls_datum_t * key)
1152 const char *hint = gnutls_psk_client_get_hint (session);
1153 unsigned char *rawkey;
1154 char *passwd;
1155 int ret;
1156 size_t res_size;
1157 gnutls_datum_t tmp;
1159 printf ("- PSK client callback. ");
1160 if (hint)
1161 printf ("PSK hint '%s'\n", hint);
1162 else
1163 printf ("No PSK hint\n");
1165 if (info.psk_username)
1166 *username = gnutls_strdup (info.psk_username);
1167 else
1169 char *tmp = NULL;
1170 size_t n;
1172 printf ("Enter PSK identity: ");
1173 fflush (stdout);
1174 getline (&tmp, &n, stdin);
1176 if (tmp == NULL)
1178 fprintf (stderr, "No username given, aborting...\n");
1179 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1182 if (tmp[strlen (tmp) - 1] == '\n')
1183 tmp[strlen (tmp) - 1] = '\0';
1184 if (tmp[strlen (tmp) - 1] == '\r')
1185 tmp[strlen (tmp) - 1] = '\0';
1187 *username = gnutls_strdup (tmp);
1188 free (tmp);
1190 if (!*username)
1191 return GNUTLS_E_MEMORY_ERROR;
1193 passwd = getpass ("Enter key: ");
1194 if (passwd == NULL)
1196 fprintf (stderr, "No key given, aborting...\n");
1197 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1200 tmp.data = passwd;
1201 tmp.size = strlen (passwd);
1203 res_size = tmp.size / 2 + 1;
1204 rawkey = gnutls_malloc (res_size);
1205 if (rawkey == NULL)
1206 return GNUTLS_E_MEMORY_ERROR;
1208 ret = gnutls_hex_decode (&tmp, rawkey, &res_size);
1209 if (ret < 0)
1211 fprintf (stderr, "Error deriving password: %s\n",
1212 gnutls_strerror (ret));
1213 gnutls_free (*username);
1214 return ret;
1217 key->data = rawkey;
1218 key->size = res_size;
1220 if (info.debug)
1222 char hexkey[41];
1223 res_size = sizeof (hexkey);
1224 gnutls_hex_encode (key, hexkey, &res_size);
1225 fprintf (stderr, "PSK username: %s\n", *username);
1226 fprintf (stderr, "PSK hint: %s\n", hint);
1227 fprintf (stderr, "PSK key: %s\n", hexkey);
1230 return 0;
1233 static void
1234 init_global_tls_stuff (void)
1236 int ret;
1238 /* X509 stuff */
1239 if (gnutls_certificate_allocate_credentials (&xcred) < 0)
1241 fprintf (stderr, "Certificate allocation memory error\n");
1242 exit (1);
1245 if (x509_cafile != NULL)
1247 ret = gnutls_certificate_set_x509_trust_file (xcred,
1248 x509_cafile, x509ctype);
1249 if (ret < 0)
1251 fprintf (stderr, "Error setting the x509 trust file\n");
1253 else
1255 printf ("Processed %d CA certificate(s).\n", ret);
1258 #ifdef ENABLE_PKI
1259 if (x509_crlfile != NULL)
1261 ret = gnutls_certificate_set_x509_crl_file (xcred, x509_crlfile,
1262 x509ctype);
1263 if (ret < 0)
1265 fprintf (stderr, "Error setting the x509 CRL file\n");
1267 else
1269 printf ("Processed %d CRL(s).\n", ret);
1272 #endif
1274 load_keys ();
1276 #ifdef ENABLE_OPENPGP
1277 if (pgp_keyring != NULL)
1279 ret =
1280 gnutls_certificate_set_openpgp_keyring_file (xcred, pgp_keyring,
1281 GNUTLS_OPENPGP_FMT_BASE64);
1282 if (ret < 0)
1284 fprintf (stderr, "Error setting the OpenPGP keyring file\n");
1287 #endif
1289 #ifdef ENABLE_SRP
1290 if (srp_username && srp_passwd)
1292 /* SRP stuff */
1293 if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0)
1295 fprintf (stderr, "SRP authentication error\n");
1298 gnutls_srp_set_client_credentials_function (srp_cred,
1299 srp_username_callback);
1301 #endif
1303 #ifdef ENABLE_PSK
1304 /* PSK stuff */
1305 if (gnutls_psk_allocate_client_credentials (&psk_cred) < 0)
1307 fprintf (stderr, "PSK authentication error\n");
1310 if (psk_username && psk_key.data)
1312 ret = gnutls_psk_set_client_credentials (psk_cred,
1313 psk_username, &psk_key,
1314 GNUTLS_PSK_KEY_HEX);
1315 if (ret < 0)
1317 fprintf (stderr, "Error setting the PSK credentials: %s\n",
1318 gnutls_strerror (ret));
1321 gnutls_psk_set_client_credentials_function (psk_cred, psk_callback);
1322 #endif
1324 #ifdef ENABLE_ANON
1325 /* ANON stuff */
1326 if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
1328 fprintf (stderr, "Anonymous authentication error\n");
1330 #endif
1334 /* Functions to manipulate sockets
1337 ssize_t
1338 socket_recv (const socket_st * socket, void *buffer, int buffer_size)
1340 int ret;
1342 if (socket->secure)
1345 ret = gnutls_record_recv (socket->session, buffer, buffer_size);
1347 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
1348 else
1351 ret = recv (socket->fd, buffer, buffer_size, 0);
1353 while (ret == -1 && errno == EINTR);
1355 return ret;
1358 ssize_t
1359 socket_send (const socket_st * socket, const void *buffer, int buffer_size)
1361 int ret;
1363 if (socket->secure)
1366 ret = gnutls_record_send (socket->session, buffer, buffer_size);
1368 while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
1369 else
1372 ret = send (socket->fd, buffer, buffer_size, 0);
1374 while (ret == -1 && errno == EINTR);
1376 if (ret > 0 && ret != buffer_size && verbose)
1377 fprintf (stderr,
1378 "*** Only sent %d bytes instead of %d.\n", ret, buffer_size);
1380 return ret;
1383 void
1384 socket_bye (socket_st * socket)
1386 int ret;
1387 if (socket->secure)
1390 ret = gnutls_bye (socket->session, GNUTLS_SHUT_WR);
1391 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
1392 if (ret < 0)
1393 fprintf (stderr, "*** gnutls_bye() error: %s\n",
1394 gnutls_strerror (ret));
1395 gnutls_deinit (socket->session);
1396 socket->session = NULL;
1399 freeaddrinfo (socket->addr_info);
1400 socket->addr_info = socket->ptr = NULL;
1402 free (socket->ip);
1403 free (socket->hostname);
1404 free (socket->service);
1406 shutdown (socket->fd, SHUT_RDWR); /* no more receptions */
1407 close (socket->fd);
1409 socket->fd = -1;
1410 socket->secure = 0;
1413 void
1414 socket_connect (const socket_st * hd)
1416 int err;
1418 printf ("Connecting to '%s:%s'...\n", hd->ip, hd->service);
1420 err = connect (hd->fd, hd->ptr->ai_addr, hd->ptr->ai_addrlen);
1421 if (err < 0)
1423 fprintf (stderr, "Cannot connect to %s:%s: %s\n", hd->hostname,
1424 hd->service, strerror (errno));
1425 exit (1);
1429 void
1430 socket_open (socket_st * hd, const char *hostname, const char *service)
1432 struct addrinfo hints, *res, *ptr;
1433 int sd, err;
1434 char buffer[MAX_BUF + 1];
1435 char portname[16] = { 0 };
1437 printf ("Resolving '%s'...\n", hostname);
1438 /* get server name */
1439 memset (&hints, 0, sizeof (hints));
1440 hints.ai_socktype = SOCK_STREAM;
1441 if ((err = getaddrinfo (hostname, service, &hints, &res)))
1443 fprintf (stderr, "Cannot resolve %s:%s: %s\n", hostname, service,
1444 gai_strerror (err));
1445 exit (1);
1448 sd = -1;
1449 for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
1451 sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
1452 if (sd == -1)
1453 continue;
1455 if ((err = getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF,
1456 portname, sizeof (portname),
1457 NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1459 fprintf (stderr, "getnameinfo(): %s\n", gai_strerror (err));
1460 freeaddrinfo (res);
1461 exit (1);
1464 break;
1467 if (sd == -1)
1469 fprintf (stderr, "socket(): %s\n", strerror (errno));
1470 exit (1);
1473 hd->secure = 0;
1474 hd->fd = sd;
1475 hd->hostname = strdup (hostname);
1476 hd->ip = strdup (buffer);
1477 hd->service = strdup (portname);
1478 hd->ptr = ptr;
1479 hd->addr_info = res;
1481 return;