Tizen 2.0 Release
[external/libgnutls26.git] / src / cli.c
1 /*
2  * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3  * 2009, 2010  Free Software Foundation, Inc.
4  *
5  * This file is part of GnuTLS.
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
21 #include <config.h>
22
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>
35
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>
41
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"
49
50 #include "common.h"
51 #include "cli-gaa.h"
52
53 #define MAX_BUF 4096
54
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;
64
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;
76
77 char *psk_username = NULL;
78 gnutls_datum_t psk_key = { NULL, 0 };
79
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;
84
85 static gaainfo info;
86
87 /* end of global stuff */
88
89 /* prototypes */
90 typedef struct
91 {
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;
101
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);
108
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);
112
113 /* Helper functions to load a certificate and key
114  * files into memory.
115  */
116 static gnutls_datum_t
117 load_file (const char *file)
118 {
119   gnutls_datum_t loaded_file = { NULL, 0 };
120   size_t length;
121
122   loaded_file.data = read_binary_file (file, &length);
123   if (loaded_file.data)
124     loaded_file.size = (unsigned int) length;
125
126   return loaded_file;
127 }
128
129 static void
130 unload_file (gnutls_datum_t data)
131 {
132   free (data.data);
133 }
134
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;
139
140 static gnutls_pkcs11_privkey_t pkcs11_key = NULL;
141
142 static gnutls_openpgp_crt_t pgp_crt = NULL;
143 static gnutls_openpgp_privkey_t pgp_key = NULL;
144
145 static void
146 get_keyid (gnutls_openpgp_keyid_t keyid, const char *str)
147 {
148   size_t keyid_size = sizeof (keyid);
149
150   if (strlen (str) != 16)
151     {
152       fprintf (stderr,
153                "The OpenPGP subkey ID has to be 16 hexadecimal characters.\n");
154       exit (1);
155     }
156
157   if (gnutls_hex2bin (str, strlen (str), keyid, &keyid_size) < 0)
158     {
159       fprintf (stderr, "Error converting hex string: %s.\n", str);
160       exit (1);
161     }
162
163   return;
164 }
165
166 /* Load the certificate and the private key.
167  */
168 static void
169 load_keys (void)
170 {
171   unsigned int crt_num;
172   int ret;
173   gnutls_datum_t data = { NULL, 0 };
174
175   if (x509_certfile != NULL && x509_keyfile != NULL)
176     {
177 #ifdef ENABLE_PKCS11
178       if (strncmp (x509_certfile, "pkcs11:", 7) == 0)
179         {
180           crt_num = 1;
181           gnutls_x509_crt_init (&x509_crt[0]);
182
183           ret =
184             gnutls_x509_crt_import_pkcs11_url (x509_crt[0], x509_certfile, 0);
185
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);
190
191           if (ret < 0)
192             {
193               fprintf (stderr, "*** Error loading cert file.\n");
194               exit (1);
195             }
196           x509_crt_size = 1;
197         }
198       else
199 #endif /* ENABLE_PKCS11 */
200         {
201
202           data = load_file (x509_certfile);
203           if (data.data == NULL)
204             {
205               fprintf (stderr, "*** Error loading cert file.\n");
206               exit (1);
207             }
208
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)
215             {
216               if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
217                 {
218                   fprintf (stderr,
219                            "*** Error loading cert file: Too many certs %d\n",
220                            crt_num);
221
222                 }
223               else
224                 {
225                   fprintf (stderr,
226                            "*** Error loading cert file: %s\n",
227                            gnutls_strerror (ret));
228                 }
229               exit (1);
230             }
231           x509_crt_size = ret;
232         }
233       fprintf (stderr, "Processed %d client certificates...\n", ret);
234
235       unload_file (data);
236
237 #ifdef ENABLE_PKCS11
238       if (strncmp (x509_keyfile, "pkcs11:", 7) == 0)
239         {
240           gnutls_pkcs11_privkey_init (&pkcs11_key);
241
242           ret =
243             gnutls_pkcs11_privkey_import_url (pkcs11_key, x509_keyfile, 0);
244           if (ret < 0)
245             {
246               fprintf (stderr, "*** Error loading url: %s\n",
247                        gnutls_strerror (ret));
248               exit (1);
249             }
250         }
251       else
252 #endif /* ENABLE_PKCS11 */
253         {
254           data = load_file (x509_keyfile);
255           if (data.data == NULL)
256             {
257               fprintf (stderr, "*** Error loading key file.\n");
258               exit (1);
259             }
260
261           gnutls_x509_privkey_init (&x509_key);
262
263           ret =
264             gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM);
265           if (ret < 0)
266             {
267               fprintf (stderr, "*** Error loading key file: %s\n",
268                        gnutls_strerror (ret));
269               exit (1);
270             }
271
272           unload_file (data);
273         }
274
275       fprintf (stderr, "Processed %d client X.509 certificates...\n",
276                x509_crt_size);
277     }
278 #ifdef ENABLE_OPENPGP
279   if (pgp_certfile != NULL && pgp_keyfile != NULL)
280     {
281       data = load_file (pgp_certfile);
282       if (data.data == NULL)
283         {
284           fprintf (stderr, "*** Error loading PGP cert file.\n");
285           exit (1);
286         }
287       gnutls_openpgp_crt_init (&pgp_crt);
288
289       ret =
290         gnutls_openpgp_crt_import (pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64);
291       if (ret < 0)
292         {
293           fprintf (stderr,
294                    "*** Error loading PGP cert file: %s\n",
295                    gnutls_strerror (ret));
296           exit (1);
297         }
298
299
300       unload_file (data);
301
302 #ifdef ENABLE_PKCS11
303       if (strncmp (pgp_keyfile, "pkcs11:", 7) == 0)
304         {
305           gnutls_pkcs11_privkey_init (&pkcs11_key);
306
307           ret = gnutls_pkcs11_privkey_import_url (pkcs11_key, pgp_keyfile, 0);
308           if (ret < 0)
309             {
310               fprintf (stderr, "*** Error loading url: %s\n",
311                        gnutls_strerror (ret));
312               exit (1);
313             }
314         }
315       else
316 #endif /* ENABLE_PKCS11 */
317         {
318
319           data = load_file (pgp_keyfile);
320           if (data.data == NULL)
321             {
322               fprintf (stderr, "*** Error loading PGP key file.\n");
323               exit (1);
324             }
325
326           gnutls_openpgp_privkey_init (&pgp_key);
327
328           ret =
329             gnutls_openpgp_privkey_import (pgp_key, &data,
330                                            GNUTLS_OPENPGP_FMT_BASE64, NULL,
331                                            0);
332           if (ret < 0)
333             {
334               fprintf (stderr,
335                        "*** Error loading PGP key file: %s\n",
336                        gnutls_strerror (ret));
337               exit (1);
338             }
339
340           unload_file (data);
341         }
342
343       if (info.pgp_subkey != NULL)
344         {
345           unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE];
346
347           if (strcasecmp (info.pgp_subkey, "auto") == 0)
348             {
349               ret = gnutls_openpgp_crt_get_auth_subkey (pgp_crt, keyid, 1);
350               if (ret < 0)
351                 {
352                   fprintf (stderr,
353                            "*** Error setting preferred sub key id (%s): %s\n",
354                            info.pgp_subkey, gnutls_strerror (ret));
355                   exit (1);
356                 }
357             }
358           else
359             get_keyid (keyid, info.pgp_subkey);
360
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)
366             {
367               fprintf (stderr,
368                        "*** Error setting preferred sub key id (%s): %s\n",
369                        info.pgp_subkey, gnutls_strerror (ret));
370               exit (1);
371             }
372         }
373
374       fprintf (stderr, "Processed 1 client PGP certificate...\n");
375     }
376 #endif
377
378 }
379
380 static int
381 cert_verify_callback (gnutls_session_t session)
382 {
383   int rc;
384   unsigned int status;
385
386   if (!x509_cafile && !pgp_keyring)
387     return 0;
388
389   rc = gnutls_certificate_verify_peers2 (session, &status);
390   if (rc != 0 || status != 0)
391     {
392       printf ("*** Verifying server certificate failed...\n");
393       if (!insecure)
394         return -1;
395     }
396
397   return 0;
398 }
399
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.
403  */
404
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)
410 {
411   char issuer_dn[256];
412   int i, ret;
413   size_t len;
414
415   if (verbose)
416     {
417       /* Print the server's trusted CAs
418        */
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");
423
424       /* print the names (if any) */
425       for (i = 0; i < nreqs; i++)
426         {
427           len = sizeof (issuer_dn);
428           ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len);
429           if (ret >= 0)
430             {
431               printf ("   [%d]: ", i);
432               printf ("%s\n", issuer_dn);
433             }
434         }
435     }
436
437   /* Select a certificate and return it.
438    * The certificate must be of any of the "sign algorithms"
439    * supported by the server.
440    */
441
442   st->cert_type = gnutls_certificate_type_get (session);
443
444   st->ncerts = 0;
445
446   if (st->cert_type == GNUTLS_CRT_X509)
447     {
448       gnutls_sign_algorithm_t cert_algo, req_algo;
449       int i, match = 0;
450
451       if (x509_crt_size > 0)
452         {
453           ret = gnutls_x509_crt_get_signature_algorithm (x509_crt[0]);
454           if (ret < 0)
455             {
456               /* error reading signature algorithm */
457               return -1;
458             }
459           cert_algo = ret;
460
461           i = 0;
462           do
463             {
464               ret =
465                 gnutls_sign_algorithm_get_requested (session, i, &req_algo);
466               if (ret >= 0 && cert_algo == req_algo)
467                 {
468                   match = 1;
469                   break;
470                 }
471
472               /* server has not requested anything specific */
473               if (i == 0 && ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
474                 {
475                   match = 1;
476                   break;
477                 }
478               i++;
479             }
480           while (ret >= 0);
481
482           if (match == 0)
483             {
484               printf
485                 ("- Could not find a suitable certificate to send to server\n");
486               return -1;
487             }
488
489           if (x509_key != NULL)
490             {
491               st->key.x509 = x509_key;
492               st->key_type = GNUTLS_PRIVKEY_X509;
493             }
494           else if (pkcs11_key != NULL)
495             {
496               st->key.pkcs11 = pkcs11_key;
497               st->key_type = GNUTLS_PRIVKEY_PKCS11;
498             }
499           else
500             {
501               printf ("- Could not find a suitable key to send to server\n");
502               return -1;
503             }
504
505           st->ncerts = x509_crt_size;
506
507           st->cert.x509 = x509_crt;
508
509           st->deinit_all = 0;
510
511           return 0;
512         }
513
514     }
515   else if (st->cert_type == GNUTLS_CRT_OPENPGP)
516     {
517       if (pgp_crt != NULL)
518         {
519
520           if (pgp_key != NULL)
521             {
522               st->key.pgp = pgp_key;
523               st->key_type = GNUTLS_PRIVKEY_OPENPGP;
524             }
525           else if (pkcs11_key != NULL)
526             {
527               st->key.pkcs11 = pkcs11_key;
528               st->key_type = GNUTLS_PRIVKEY_PKCS11;
529             }
530           else
531             {
532               printf ("- Could not find a suitable key to send to server\n");
533               return -1;
534             }
535
536           st->ncerts = 1;
537
538           st->cert.pgp = pgp_crt;
539
540           st->deinit_all = 0;
541
542           return 0;
543         }
544     }
545
546   printf ("- Successfully sent %d certificate(s) to server.\n", st->ncerts);
547   return 0;
548
549 }
550
551 /* initializes a gnutls_session_t with some defaults.
552  */
553 static gnutls_session_t
554 init_tls_session (const char *hostname)
555 {
556   const char *err;
557
558   gnutls_session_t session;
559
560   gnutls_init (&session, GNUTLS_CLIENT);
561
562   if (gnutls_priority_set_direct (session, info.priorities, &err) < 0)
563     {
564       fprintf (stderr, "Syntax error at: %s\n", err);
565       exit (1);
566     }
567
568   /* allow the use of private ciphersuites.
569    */
570   if (disable_extensions == 0)
571     {
572       gnutls_handshake_set_private_extensions (session, 1);
573       gnutls_server_name_set (session, GNUTLS_NAME_DNS, hostname,
574                               strlen (hostname));
575     }
576
577   gnutls_dh_set_prime_bits (session, 512);
578
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);
585
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);
589
590   /* send the fingerprint */
591 #ifdef ENABLE_OPENPGP
592   if (fingerprint != 0)
593     gnutls_openpgp_send_cert (session, GNUTLS_OPENPGP_CERT_FINGERPRINT);
594 #endif
595
596   /* use the max record size extension */
597   if (record_max_size > 0 && disable_extensions == 0)
598     {
599       if (gnutls_record_set_max_size (session, record_max_size) < 0)
600         {
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);
606         }
607     }
608
609 #ifdef ENABLE_SESSION_TICKET
610   if (disable_extensions == 0 && !info.noticket)
611     gnutls_session_ticket_enable_client (session);
612 #endif
613
614   return session;
615 }
616
617 static void gaa_parser (int argc, char **argv);
618
619 /* Returns zero if the error code was successfully handled.
620  */
621 static int
622 handle_error (socket_st * hd, int err)
623 {
624   int alert, ret;
625   const char *err_type, *str;
626
627   if (err >= 0)
628     return 0;
629
630   if (gnutls_error_is_fatal (err) == 0)
631     {
632       ret = 0;
633       err_type = "Non fatal";
634     }
635   else
636     {
637       ret = err;
638       err_type = "Fatal";
639     }
640
641   str = gnutls_strerror (err);
642   if (str == NULL)
643     str = str_unknown;
644   fprintf (stderr, "*** %s error: %s\n", err_type, str);
645
646   if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
647       || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
648     {
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);
654
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.
659        */
660     }
661
662   check_rehandshake (hd, err);
663
664   return ret;
665 }
666
667 int starttls_alarmed = 0;
668
669 #ifndef _WIN32
670 static void
671 starttls_alarm (int signum)
672 {
673   starttls_alarmed = 1;
674 }
675 #endif
676
677 static void
678 tls_log_func (int level, const char *str)
679 {
680   fprintf (stderr, "|<%d>| %s", level, str);
681 }
682
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
687  */
688 static int check_net_or_keyboard_input(socket_st* hd)
689 {
690   int maxfd;
691   fd_set rset;
692   int err;
693   struct timeval tv;
694
695   do
696     {
697       FD_ZERO (&rset);
698       FD_SET (fileno (stdin), &rset);
699       FD_SET (hd->fd, &rset);
700
701       maxfd = MAX (fileno (stdin), hd->fd);
702       tv.tv_sec = 0;
703       tv.tv_usec = 500 * 1000;
704
705       if (hd->secure == 1)
706         if (gnutls_record_check_pending(hd->session))
707           return IN_NET;
708
709       err = select (maxfd + 1, &rset, NULL, NULL, &tv);
710       if (err < 0)
711         continue;
712
713       if (FD_ISSET (hd->fd, &rset))
714         return IN_NET;
715
716
717       if (FD_ISSET (fileno (stdin), &rset))
718         return IN_KEYBOARD;
719     }
720   while(err == 0);
721   
722   return IN_NONE;
723 }
724
725 int
726 main (int argc, char **argv)
727 {
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;
738
739   set_program_name (argv[0]);
740
741   if ((ret = gnutls_global_init ()) < 0)
742     {
743       fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
744       exit (1);
745     }
746
747   if ((ret = gnutls_global_init_extra ()) < 0)
748     {
749       fprintf (stderr, "global_init_extra: %s\n", gnutls_strerror (ret));
750       exit (1);
751     }
752
753 #ifdef ENABLE_PKCS11
754   pkcs11_common ();
755 #endif
756   gaa_parser (argc, argv);
757   if (hostname == NULL)
758     {
759       fprintf (stderr, "No hostname given\n");
760       exit (1);
761     }
762
763   gnutls_global_set_log_function (tls_log_func);
764   gnutls_global_set_log_level (info.debug);
765
766   sockets_init ();
767
768 #ifndef _WIN32
769   signal (SIGPIPE, SIG_IGN);
770 #endif
771
772   init_global_tls_stuff ();
773
774   socket_open (&hd, hostname, service);
775   socket_connect (&hd);
776
777   hd.session = init_tls_session (hostname);
778   if (starttls)
779     goto after_handshake;
780
781   for (i = 0; i < 2; i++)
782     {
783
784
785       if (i == 1)
786         {
787           hd.session = init_tls_session (hostname);
788           gnutls_session_set_data (hd.session, session_data,
789                                    session_data_size);
790           free (session_data);
791         }
792
793       ret = do_handshake (&hd);
794
795       if (ret < 0)
796         {
797           fprintf (stderr, "*** Handshake has failed\n");
798           gnutls_perror (ret);
799           gnutls_deinit (hd.session);
800           return 1;
801         }
802       else
803         {
804           printf ("- Handshake was completed\n");
805           if (gnutls_session_is_resumed (hd.session) != 0)
806             printf ("*** This is a resumed session\n");
807         }
808
809       if (resume != 0 && i == 0)
810         {
811
812           gnutls_session_get_data (hd.session, NULL, &session_data_size);
813           session_data = malloc (session_data_size);
814
815           gnutls_session_get_data (hd.session, session_data,
816                                    &session_data_size);
817
818           gnutls_session_get_id (hd.session, NULL, &session_id_size);
819
820           session_id = malloc (session_id_size);
821           gnutls_session_get_id (hd.session, session_id, &session_id_size);
822
823           /* print some information */
824           print_info (hd.session, hostname, info.insecure);
825
826           printf ("- Disconnecting\n");
827           socket_bye (&hd);
828
829           printf
830             ("\n\n- Connecting again- trying to resume previous session\n");
831           socket_open (&hd, hostname, service);
832           socket_connect (&hd);
833         }
834       else
835         {
836           break;
837         }
838     }
839
840 after_handshake:
841
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");
845
846   if (rehandshake)
847     {
848       ret = do_handshake (&hd);
849
850       if (ret < 0)
851         {
852           fprintf (stderr, "*** ReHandshake has failed\n");
853           gnutls_perror (ret);
854           gnutls_deinit (hd.session);
855           return 1;
856         }
857       else
858         {
859           printf ("- ReHandshake was completed\n");
860         }
861     }
862
863 #ifndef _WIN32
864   signal (SIGALRM, &starttls_alarm);
865 #endif
866
867   fflush (stdout);
868   fflush (stderr);
869
870   /* do not buffer */
871 #if !(defined _WIN32 || defined __WIN32__)
872   setbuf (stdin, NULL);
873 #endif
874   setbuf (stdout, NULL);
875   setbuf (stderr, NULL);
876
877   for (;;)
878     {
879       if (starttls_alarmed && !hd.secure)
880         {
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)
887             {
888               fprintf (stderr, "*** Handshake has failed\n");
889               user_term = 1;
890               retval = 1;
891               break;
892             }
893         }
894
895       inp = check_net_or_keyboard_input(&hd);
896
897       if (inp == IN_NET)
898         {
899           memset (buffer, 0, MAX_BUF + 1);
900           ret = socket_recv (&hd, buffer, MAX_BUF);
901
902           if (ret == 0)
903             {
904               printf ("- Peer has closed the GnuTLS connection\n");
905               break;
906             }
907           else if (handle_error (&hd, ret) < 0 && user_term == 0)
908             {
909               fprintf (stderr,
910                        "*** Server has terminated the connection abnormally.\n");
911               retval = 1;
912               break;
913             }
914           else if (ret > 0)
915             {
916               if (verbose != 0)
917                 printf ("- Received[%d]: ", ret);
918               for (ii = 0; ii < ret; ii++)
919                 {
920                   fputc (buffer[ii], stdout);
921                 }
922               fflush (stdout);
923             }
924
925           if (user_term != 0)
926             break;
927         }
928
929       if (inp == IN_KEYBOARD)
930         {
931           if ((bytes = read (fileno (stdin), buffer, MAX_BUF - 1)) <= 0)
932             {
933               if (hd.secure == 0)
934                 {
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)
942                     {
943                       fprintf (stderr, "*** Handshake has failed\n");
944                       user_term = 1;
945                       retval = 1;
946                       break;
947                     }
948                 }
949               else
950                 {
951                   user_term = 1;
952                   break;
953                 }
954               continue;
955             }
956
957           buffer[bytes] = 0;
958           if (crlf != 0)
959             {
960               char *b = strchr (buffer, '\n');
961               if (b != NULL)
962                 {
963                   strcpy (b, "\r\n");
964                   bytes++;
965                 }
966             }
967
968           ret = socket_send (&hd, buffer, bytes);
969
970           if (ret > 0)
971             {
972               if (verbose != 0)
973                 printf ("- Sent: %d bytes\n", ret);
974             }
975           else
976             handle_error (&hd, ret);
977
978         }
979     }
980
981   if (user_term != 0)
982     socket_bye (&hd);
983   else
984     gnutls_deinit (hd.session);
985
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
994
995   gnutls_certificate_free_credentials (xcred);
996
997 #ifdef ENABLE_ANON
998   gnutls_anon_free_client_credentials (anon_cred);
999 #endif
1000
1001   gnutls_global_deinit ();
1002
1003   return retval;
1004 }
1005
1006 void
1007 gaa_parser (int argc, char **argv)
1008 {
1009   if (gaa (argc, argv, &info) != -1)
1010     {
1011       fprintf (stderr,
1012                "Error in the arguments. Use the --help or -h parameters to get more information.\n");
1013       exit (1);
1014     }
1015
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;
1026
1027   if (info.fmtder == 0)
1028     x509ctype = GNUTLS_X509_FMT_PEM;
1029   else
1030     x509ctype = GNUTLS_X509_FMT_DER;
1031
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;
1040
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;
1047
1048   pgp_keyring = info.pgp_keyring;
1049
1050   crlf = info.crlf;
1051
1052   if (info.rest_args == NULL)
1053     hostname = "localhost";
1054   else
1055     hostname = info.rest_args;
1056 }
1057
1058 void cli_version (void);
1059
1060 void
1061 cli_version (void)
1062 {
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);
1068 }
1069
1070
1071 static void
1072 check_rehandshake (socket_st * socket, int ret)
1073 {
1074   if (socket->secure && ret == GNUTLS_E_REHANDSHAKE)
1075     {
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.
1080        */
1081       printf ("*** Received rehandshake request\n");
1082       /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
1083
1084       ret = do_handshake (socket);
1085
1086       if (ret == 0)
1087         {
1088           printf ("*** Rehandshake was performed.\n");
1089         }
1090       else
1091         {
1092           printf ("*** Rehandshake Failed.\n");
1093         }
1094     }
1095 }
1096
1097
1098 static int
1099 do_handshake (socket_st * socket)
1100 {
1101   int ret;
1102
1103   gnutls_transport_set_ptr (socket->session,
1104                             (gnutls_transport_ptr_t)
1105                             gl_fd_to_handle (socket->fd));
1106   do
1107     {
1108       ret = gnutls_handshake (socket->session);
1109
1110       if (ret < 0)
1111         {
1112           handle_error (socket, ret);
1113         }
1114     }
1115   while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
1116
1117   if (ret == 0)
1118     {
1119       /* print some information */
1120       print_info (socket->session, socket->hostname, info.insecure);
1121
1122
1123       socket->secure = 1;
1124
1125     }
1126   else
1127     {
1128       gnutls_alert_send_appropriate (socket->session, ret);
1129       shutdown (socket->fd, SHUT_RDWR);
1130     }
1131   return ret;
1132 }
1133
1134 static int
1135 srp_username_callback (gnutls_session_t session,
1136                        char **username, char **password)
1137 {
1138   if (srp_username == NULL || srp_passwd == NULL)
1139     {
1140       return -1;
1141     }
1142
1143   *username = gnutls_strdup (srp_username);
1144   *password = gnutls_strdup (srp_passwd);
1145
1146   return 0;
1147 }
1148
1149 static int
1150 psk_callback (gnutls_session_t session, char **username, gnutls_datum_t * key)
1151 {
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;
1158
1159   printf ("- PSK client callback. ");
1160   if (hint)
1161     printf ("PSK hint '%s'\n", hint);
1162   else
1163     printf ("No PSK hint\n");
1164
1165   if (info.psk_username)
1166     *username = gnutls_strdup (info.psk_username);
1167   else
1168     {
1169       char *tmp = NULL;
1170       size_t n;
1171
1172       printf ("Enter PSK identity: ");
1173       fflush (stdout);
1174       getline (&tmp, &n, stdin);
1175
1176       if (tmp == NULL)
1177         {
1178           fprintf (stderr, "No username given, aborting...\n");
1179           return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1180         }
1181
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';
1186
1187       *username = gnutls_strdup (tmp);
1188       free (tmp);
1189     }
1190   if (!*username)
1191     return GNUTLS_E_MEMORY_ERROR;
1192
1193   passwd = getpass ("Enter key: ");
1194   if (passwd == NULL)
1195     {
1196       fprintf (stderr, "No key given, aborting...\n");
1197       return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1198     }
1199
1200   tmp.data = passwd;
1201   tmp.size = strlen (passwd);
1202
1203   res_size = tmp.size / 2 + 1;
1204   rawkey = gnutls_malloc (res_size);
1205   if (rawkey == NULL)
1206     return GNUTLS_E_MEMORY_ERROR;
1207
1208   ret = gnutls_hex_decode (&tmp, rawkey, &res_size);
1209   if (ret < 0)
1210     {
1211       fprintf (stderr, "Error deriving password: %s\n",
1212                gnutls_strerror (ret));
1213       gnutls_free (*username);
1214       return ret;
1215     }
1216
1217   key->data = rawkey;
1218   key->size = res_size;
1219
1220   if (info.debug)
1221     {
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);
1228     }
1229
1230   return 0;
1231 }
1232
1233 static void
1234 init_global_tls_stuff (void)
1235 {
1236   int ret;
1237
1238   /* X509 stuff */
1239   if (gnutls_certificate_allocate_credentials (&xcred) < 0)
1240     {
1241       fprintf (stderr, "Certificate allocation memory error\n");
1242       exit (1);
1243     }
1244
1245   if (x509_cafile != NULL)
1246     {
1247       ret = gnutls_certificate_set_x509_trust_file (xcred,
1248                                                     x509_cafile, x509ctype);
1249       if (ret < 0)
1250         {
1251           fprintf (stderr, "Error setting the x509 trust file\n");
1252         }
1253       else
1254         {
1255           printf ("Processed %d CA certificate(s).\n", ret);
1256         }
1257     }
1258 #ifdef ENABLE_PKI
1259   if (x509_crlfile != NULL)
1260     {
1261       ret = gnutls_certificate_set_x509_crl_file (xcred, x509_crlfile,
1262                                                   x509ctype);
1263       if (ret < 0)
1264         {
1265           fprintf (stderr, "Error setting the x509 CRL file\n");
1266         }
1267       else
1268         {
1269           printf ("Processed %d CRL(s).\n", ret);
1270         }
1271     }
1272 #endif
1273
1274   load_keys ();
1275
1276 #ifdef ENABLE_OPENPGP
1277   if (pgp_keyring != NULL)
1278     {
1279       ret =
1280         gnutls_certificate_set_openpgp_keyring_file (xcred, pgp_keyring,
1281                                                      GNUTLS_OPENPGP_FMT_BASE64);
1282       if (ret < 0)
1283         {
1284           fprintf (stderr, "Error setting the OpenPGP keyring file\n");
1285         }
1286     }
1287 #endif
1288
1289 #ifdef ENABLE_SRP
1290   if (srp_username && srp_passwd)
1291     {
1292       /* SRP stuff */
1293       if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0)
1294         {
1295           fprintf (stderr, "SRP authentication error\n");
1296         }
1297
1298       gnutls_srp_set_client_credentials_function (srp_cred,
1299                                                   srp_username_callback);
1300     }
1301 #endif
1302
1303 #ifdef ENABLE_PSK
1304   /* PSK stuff */
1305   if (gnutls_psk_allocate_client_credentials (&psk_cred) < 0)
1306     {
1307       fprintf (stderr, "PSK authentication error\n");
1308     }
1309
1310   if (psk_username && psk_key.data)
1311     {
1312       ret = gnutls_psk_set_client_credentials (psk_cred,
1313                                                psk_username, &psk_key,
1314                                                GNUTLS_PSK_KEY_HEX);
1315       if (ret < 0)
1316         {
1317           fprintf (stderr, "Error setting the PSK credentials: %s\n",
1318                    gnutls_strerror (ret));
1319         }
1320     }
1321   gnutls_psk_set_client_credentials_function (psk_cred, psk_callback);
1322 #endif
1323
1324 #ifdef ENABLE_ANON
1325   /* ANON stuff */
1326   if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
1327     {
1328       fprintf (stderr, "Anonymous authentication error\n");
1329     }
1330 #endif
1331
1332 }
1333
1334 /* Functions to manipulate sockets
1335  */
1336
1337 ssize_t
1338 socket_recv (const socket_st * socket, void *buffer, int buffer_size)
1339 {
1340   int ret;
1341
1342   if (socket->secure)
1343     do
1344       {
1345         ret = gnutls_record_recv (socket->session, buffer, buffer_size);
1346       }
1347     while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
1348   else
1349     do
1350       {
1351         ret = recv (socket->fd, buffer, buffer_size, 0);
1352       }
1353     while (ret == -1 && errno == EINTR);
1354
1355   return ret;
1356 }
1357
1358 ssize_t
1359 socket_send (const socket_st * socket, const void *buffer, int buffer_size)
1360 {
1361   int ret;
1362
1363   if (socket->secure)
1364     do
1365       {
1366         ret = gnutls_record_send (socket->session, buffer, buffer_size);
1367       }
1368     while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
1369   else
1370     do
1371       {
1372         ret = send (socket->fd, buffer, buffer_size, 0);
1373       }
1374     while (ret == -1 && errno == EINTR);
1375
1376   if (ret > 0 && ret != buffer_size && verbose)
1377     fprintf (stderr,
1378              "*** Only sent %d bytes instead of %d.\n", ret, buffer_size);
1379
1380   return ret;
1381 }
1382
1383 void
1384 socket_bye (socket_st * socket)
1385 {
1386   int ret;
1387   if (socket->secure)
1388     {
1389       do
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;
1397     }
1398
1399   freeaddrinfo (socket->addr_info);
1400   socket->addr_info = socket->ptr = NULL;
1401
1402   free (socket->ip);
1403   free (socket->hostname);
1404   free (socket->service);
1405
1406   shutdown (socket->fd, SHUT_RDWR);     /* no more receptions */
1407   close (socket->fd);
1408
1409   socket->fd = -1;
1410   socket->secure = 0;
1411 }
1412
1413 void
1414 socket_connect (const socket_st * hd)
1415 {
1416   int err;
1417
1418   printf ("Connecting to '%s:%s'...\n", hd->ip, hd->service);
1419
1420   err = connect (hd->fd, hd->ptr->ai_addr, hd->ptr->ai_addrlen);
1421   if (err < 0)
1422     {
1423       fprintf (stderr, "Cannot connect to %s:%s: %s\n", hd->hostname,
1424                hd->service, strerror (errno));
1425       exit (1);
1426     }
1427 }
1428
1429 void
1430 socket_open (socket_st * hd, const char *hostname, const char *service)
1431 {
1432   struct addrinfo hints, *res, *ptr;
1433   int sd, err;
1434   char buffer[MAX_BUF + 1];
1435   char portname[16] = { 0 };
1436
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)))
1442     {
1443       fprintf (stderr, "Cannot resolve %s:%s: %s\n", hostname, service,
1444                gai_strerror (err));
1445       exit (1);
1446     }
1447
1448   sd = -1;
1449   for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
1450     {
1451       sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
1452       if (sd == -1)
1453         continue;
1454
1455       if ((err = getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF,
1456                               portname, sizeof (portname),
1457                               NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1458         {
1459           fprintf (stderr, "getnameinfo(): %s\n", gai_strerror (err));
1460           freeaddrinfo (res);
1461           exit (1);
1462         }
1463
1464       break;
1465     }
1466
1467   if (sd == -1)
1468     {
1469       fprintf (stderr, "socket(): %s\n", strerror (errno));
1470       exit (1);
1471     }
1472
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;
1480
1481   return;
1482 }