Merge branch 'master' of ssh://git.sv.gnu.org/srv/git/gnutls
[gnutls:gnutls.git] / src / cli.c
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation
3  * Copyright (C) 2000,2001,2002,2003 Nikos Mavrogiannopoulos
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 <gcrypt.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
48 #include "common.h"
49 #include "cli-gaa.h"
50
51 #define SA struct sockaddr
52 #define ERR(err,s) do { if (err==-1) {perror(s);return(1);} } while (0)
53 #define MAX_BUF 4096
54
55 /* global stuff here */
56 int resume, starttls, insecure;
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 static int protocol_priority[PRI_MAX];
88 static int kx_priority[PRI_MAX];
89 static int cipher_priority[PRI_MAX];
90 static int comp_priority[PRI_MAX];
91 static int mac_priority[PRI_MAX];
92 static int cert_type_priority[PRI_MAX];
93
94 /* end of global stuff */
95
96 /* prototypes */
97 typedef struct
98 {
99   int fd;
100   gnutls_session_t session;
101   int secure;
102   char *hostname;
103   char *ip;
104   char *service;
105   struct addrinfo *ptr;
106   struct addrinfo *addr_info;
107 } socket_st;
108
109 ssize_t socket_recv (const socket_st * socket, void *buffer, int buffer_size);
110 ssize_t socket_send (const socket_st * socket, const void *buffer,
111                      int buffer_size);
112 void socket_open (socket_st * hd, const char *hostname, const char *service);
113 void socket_connect (const socket_st * hd);
114 void socket_bye (socket_st * socket);
115
116 static void check_rehandshake (socket_st * socket, int ret);
117 static int do_handshake (socket_st * socket);
118 static void init_global_tls_stuff (void);
119
120
121 #undef MAX
122 #define MAX(X,Y) (X >= Y ? X : Y);
123
124
125 /* Helper functions to load a certificate and key
126  * files into memory.
127  */
128 static gnutls_datum_t
129 load_file (const char *file)
130 {
131   FILE *f;
132   gnutls_datum_t loaded_file = { NULL, 0 };
133   long filelen;
134   void *ptr;
135
136   if (!(f = fopen (file, "r"))
137       || fseek (f, 0, SEEK_END) != 0
138       || (filelen = ftell (f)) < 0
139       || fseek (f, 0, SEEK_SET) != 0
140       || !(ptr = malloc ((size_t) filelen))
141       || fread (ptr, 1, (size_t) filelen, f) < (size_t) filelen)
142     {
143       return loaded_file;
144     }
145
146   loaded_file.data = ptr;
147   loaded_file.size = (unsigned int) filelen;
148   return loaded_file;
149 }
150
151 static void
152 unload_file (gnutls_datum_t data)
153 {
154   free (data.data);
155 }
156
157 #define MAX_CRT 6
158 static unsigned int x509_crt_size;
159 static gnutls_x509_crt_t x509_crt[MAX_CRT];
160 static gnutls_x509_privkey_t x509_key = NULL;
161
162 static gnutls_openpgp_crt_t pgp_crt = NULL;
163 static gnutls_openpgp_privkey_t pgp_key = NULL;
164
165 static void
166 get_keyid (gnutls_openpgp_keyid_t keyid, const char *str)
167 {
168   size_t keyid_size = sizeof (keyid);
169
170   if (strlen (str) != 16)
171     {
172       fprintf (stderr,
173                "The OpenPGP subkey ID has to be 16 hexadecimal characters.\n");
174       exit (1);
175     }
176
177   if (gnutls_hex2bin (str, strlen (str), keyid, &keyid_size) < 0)
178     {
179       fprintf (stderr, "Error converting hex string: %s.\n", str);
180       exit (1);
181     }
182
183   return;
184 }
185
186 /* Load the certificate and the private key.
187  */
188 static void
189 load_keys (void)
190 {
191   unsigned int crt_num;
192   int ret;
193   gnutls_datum_t data;
194
195   if (x509_certfile != NULL && x509_keyfile != NULL)
196     {
197       data = load_file (x509_certfile);
198       if (data.data == NULL)
199         {
200           fprintf (stderr, "*** Error loading cert file.\n");
201           exit (1);
202         }
203
204       crt_num = MAX_CRT;
205       ret =
206         gnutls_x509_crt_list_import (x509_crt, &crt_num, &data,
207                                      GNUTLS_X509_FMT_PEM,
208                                      GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
209       if (ret < 0)
210         {
211           if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
212             {
213               fprintf (stderr,
214                        "*** Error loading cert file: Too many certs %d\n",
215                        crt_num);
216
217             }
218           else
219             {
220               fprintf (stderr,
221                        "*** Error loading cert file: %s\n",
222                        gnutls_strerror (ret));
223             }
224           exit (1);
225         }
226       x509_crt_size = ret;
227       fprintf (stderr, "Processed %d client certificates...\n", ret);
228
229       unload_file (data);
230
231       data = load_file (x509_keyfile);
232       if (data.data == NULL)
233         {
234           fprintf (stderr, "*** Error loading key file.\n");
235           exit (1);
236         }
237
238       gnutls_x509_privkey_init (&x509_key);
239
240       ret = gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM);
241       if (ret < 0)
242         {
243           fprintf (stderr, "*** Error loading key file: %s\n",
244                    gnutls_strerror (ret));
245           exit (1);
246         }
247
248       unload_file (data);
249
250       fprintf (stderr, "Processed %d client X.509 certificates...\n",
251                x509_crt_size);
252     }
253 #ifdef ENABLE_OPENPGP
254   if (pgp_certfile != NULL && pgp_keyfile != NULL)
255     {
256       data = load_file (pgp_certfile);
257       if (data.data == NULL)
258         {
259           fprintf (stderr, "*** Error loading PGP cert file.\n");
260           exit (1);
261         }
262       gnutls_openpgp_crt_init (&pgp_crt);
263
264       ret =
265         gnutls_openpgp_crt_import (pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64);
266       if (ret < 0)
267         {
268           fprintf (stderr,
269                    "*** Error loading PGP cert file: %s\n",
270                    gnutls_strerror (ret));
271           exit (1);
272         }
273
274
275       unload_file (data);
276
277       data = load_file (pgp_keyfile);
278       if (data.data == NULL)
279         {
280           fprintf (stderr, "*** Error loading PGP key file.\n");
281           exit (1);
282         }
283
284       gnutls_openpgp_privkey_init (&pgp_key);
285
286       ret =
287         gnutls_openpgp_privkey_import (pgp_key, &data,
288                                        GNUTLS_OPENPGP_FMT_BASE64, NULL, 0);
289       if (ret < 0)
290         {
291           fprintf (stderr,
292                    "*** Error loading PGP key file: %s\n",
293                    gnutls_strerror (ret));
294           exit (1);
295         }
296
297       unload_file (data);
298
299       if (info.pgp_subkey != NULL)
300         {
301           gnutls_openpgp_keyid_t keyid;
302
303           if (strcasecmp (info.pgp_subkey, "auto") == 0)
304             {
305               ret = gnutls_openpgp_crt_get_auth_subkey (pgp_crt, keyid, 1);
306               if (ret < 0)
307                 {
308                   fprintf (stderr,
309                            "*** Error setting preferred sub key id (%s): %s\n",
310                            info.pgp_subkey, gnutls_strerror (ret));
311                   exit (1);
312                 }
313             }
314           else
315             get_keyid (keyid, info.pgp_subkey);
316
317           ret = gnutls_openpgp_crt_set_preferred_key_id (pgp_crt, keyid);
318           if (ret >= 0)
319             ret =
320               gnutls_openpgp_privkey_set_preferred_key_id (pgp_key, keyid);
321           if (ret < 0)
322             {
323               fprintf (stderr,
324                        "*** Error setting preferred sub key id (%s): %s\n",
325                        info.pgp_subkey, gnutls_strerror (ret));
326               exit (1);
327             }
328         }
329
330       fprintf (stderr, "Processed 1 client PGP certificate...\n");
331     }
332 #endif
333
334 }
335
336
337
338 /* This callback should be associated with a session by calling
339  * gnutls_certificate_client_set_retrieve_function( session, cert_callback),
340  * before a handshake.
341  */
342
343 static int
344 cert_callback (gnutls_session_t session,
345                const gnutls_datum_t * req_ca_rdn, int nreqs,
346                const gnutls_pk_algorithm_t * sign_algos,
347                int sign_algos_length, gnutls_retr_st * st)
348 {
349   char issuer_dn[256];
350   int i, ret;
351   size_t len;
352
353   if (verbose)
354     {
355
356       /* Print the server's trusted CAs
357        */
358       if (nreqs > 0)
359         printf ("- Server's trusted authorities:\n");
360       else
361         printf ("- Server did not send us any trusted authorities names.\n");
362
363       /* print the names (if any) */
364       for (i = 0; i < nreqs; i++)
365         {
366           len = sizeof (issuer_dn);
367           ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len);
368           if (ret >= 0)
369             {
370               printf ("   [%d]: ", i);
371               printf ("%s\n", issuer_dn);
372             }
373         }
374     }
375
376   /* Select a certificate and return it.
377    * The certificate must be of any of the "sign algorithms"
378    * supported by the server.
379    */
380
381   st->type = gnutls_certificate_type_get (session);
382
383   st->ncerts = 0;
384
385   if (st->type == GNUTLS_CRT_X509)
386     {
387       if (x509_crt != NULL && x509_key != NULL)
388         {
389           st->ncerts = x509_crt_size;
390
391           st->cert.x509 = x509_crt;
392           st->key.x509 = x509_key;
393
394           st->deinit_all = 0;
395
396           return 0;
397         }
398     }
399   else if (st->type == GNUTLS_CRT_OPENPGP)
400     {
401       if (pgp_key != NULL && pgp_crt != NULL)
402         {
403           st->ncerts = 1;
404
405           st->cert.pgp = pgp_crt;
406           st->key.pgp = pgp_key;
407
408           st->deinit_all = 0;
409
410           return 0;
411         }
412     }
413
414   printf ("- Successfully sent %d certificate(s) to server.\n", st->ncerts);
415   return 0;
416
417 }
418
419 /* initializes a gnutls_session_t with some defaults.
420  */
421 static gnutls_session_t
422 init_tls_session (const char *hostname)
423 {
424   const char *err;
425
426   gnutls_session_t session;
427
428   gnutls_init (&session, GNUTLS_CLIENT);
429
430   if (gnutls_priority_set_direct (session, info.priorities, &err) < 0)
431     {
432       fprintf (stderr, "Syntax error at: %s\n", err);
433       exit (1);
434     }
435
436   /* allow the use of private ciphersuites.
437    */
438   if (disable_extensions == 0)
439     {
440       gnutls_handshake_set_private_extensions (session, 1);
441       gnutls_server_name_set (session, GNUTLS_NAME_DNS, hostname,
442                               strlen (hostname));
443       if (cert_type_priority[0])
444         gnutls_certificate_type_set_priority (session, cert_type_priority);
445     }
446
447   if (cipher_priority[0])
448     gnutls_cipher_set_priority (session, cipher_priority);
449   if (comp_priority[0])
450     gnutls_compression_set_priority (session, comp_priority);
451   if (kx_priority[0])
452     gnutls_kx_set_priority (session, kx_priority);
453   if (protocol_priority[0])
454     gnutls_protocol_set_priority (session, protocol_priority);
455   if (mac_priority[0])
456     gnutls_mac_set_priority (session, mac_priority);
457
458   gnutls_dh_set_prime_bits (session, 512);
459
460   gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred);
461   if (srp_cred)
462     gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred);
463   if (psk_cred)
464     gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred);
465   gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
466
467   gnutls_certificate_client_set_retrieve_function (xcred, cert_callback);
468
469   /* send the fingerprint */
470 #ifdef ENABLE_OPENPGP
471   if (fingerprint != 0)
472     gnutls_openpgp_send_cert (session, GNUTLS_OPENPGP_CERT_FINGERPRINT);
473 #endif
474
475   /* use the max record size extension */
476   if (record_max_size > 0 && disable_extensions == 0)
477     {
478       if (gnutls_record_set_max_size (session, record_max_size) < 0)
479         {
480           fprintf (stderr,
481                    "Cannot set the maximum record size to %d.\n",
482                    record_max_size);
483           fprintf (stderr, "Possible values: 512, 1024, 2048, 4096.\n");
484           exit (1);
485         }
486     }
487
488 #ifdef ENABLE_OPRFI
489   if (info.opaque_prf_input)
490     gnutls_oprfi_enable_client (session, strlen (info.opaque_prf_input),
491                                 info.opaque_prf_input);
492 #endif
493
494   return session;
495 }
496
497 static void gaa_parser (int argc, char **argv);
498
499 /* Returns zero if the error code was successfully handled.
500  */
501 static int
502 handle_error (socket_st * hd, int err)
503 {
504   int alert, ret;
505   const char *err_type, *str;
506
507   if (err >= 0)
508     return 0;
509
510   if (gnutls_error_is_fatal (err) == 0)
511     {
512       ret = 0;
513       err_type = "Non fatal";
514     }
515   else
516     {
517       ret = err;
518       err_type = "Fatal";
519     }
520
521   str = gnutls_strerror (err);
522   if (str == NULL)
523     str = str_unknown;
524   fprintf (stderr, "*** %s error: %s\n", err_type, str);
525
526   if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
527       || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
528     {
529       alert = gnutls_alert_get (hd->session);
530       str = gnutls_alert_get_name (alert);
531       if (str == NULL)
532         str = str_unknown;
533       printf ("*** Received alert [%d]: %s\n", alert, str);
534
535       /* In SRP if the alert is MISSING_SRP_USERNAME,
536        * we should read the username/password and
537        * call gnutls_handshake(). This is not implemented
538        * here.
539        */
540     }
541
542   check_rehandshake (hd, err);
543
544   return ret;
545 }
546
547 int starttls_alarmed = 0;
548
549 static void
550 starttls_alarm (int signum)
551 {
552   starttls_alarmed = 1;
553 }
554
555 static void
556 tls_log_func (int level, const char *str)
557 {
558   fprintf (stderr, "|<%d>| %s", level, str);
559 }
560
561 int
562 main (int argc, char **argv)
563 {
564   int err, ret;
565   int ii, i;
566   char buffer[MAX_BUF + 1];
567   char *session_data = NULL;
568   char *session_id = NULL;
569   size_t session_data_size;
570   size_t session_id_size;
571   fd_set rset;
572   int maxfd;
573   struct timeval tv;
574   int user_term = 0;
575   socket_st hd;
576
577   set_program_name (argv[0]);
578
579   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
580
581 #ifdef gcry_fips_mode_active
582   if (gcry_fips_mode_active ())
583     {
584       ret = gnutls_register_md5_handler ();
585       if (ret)
586         fprintf (stderr, "gnutls_register_md5_handler: %s\n",
587                  gnutls_strerror (ret));
588     }
589 #endif
590
591   if ((ret = gnutls_global_init ()) < 0)
592     {
593       fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
594       exit (1);
595     }
596
597   if ((ret = gnutls_global_init_extra ()) < 0)
598     {
599       fprintf (stderr, "global_init_extra: %s\n", gnutls_strerror (ret));
600       exit (1);
601     }
602
603   gaa_parser (argc, argv);
604   if (hostname == NULL)
605     {
606       fprintf (stderr, "No hostname given\n");
607       exit (1);
608     }
609
610   gnutls_global_set_log_function (tls_log_func);
611   gnutls_global_set_log_level (info.debug);
612
613   sockets_init ();
614
615 #ifndef _WIN32
616   signal (SIGPIPE, SIG_IGN);
617 #endif
618
619   init_global_tls_stuff ();
620
621   socket_open (&hd, hostname, service);
622   socket_connect (&hd);
623
624   hd.session = init_tls_session (hostname);
625   if (starttls)
626     goto after_handshake;
627
628   for (i = 0; i < 2; i++)
629     {
630
631
632       if (i == 1)
633         {
634           hd.session = init_tls_session (hostname);
635           gnutls_session_set_data (hd.session, session_data,
636                                    session_data_size);
637           free (session_data);
638         }
639
640       ret = do_handshake (&hd);
641
642       if (ret < 0)
643         {
644           fprintf (stderr, "*** Handshake has failed\n");
645           gnutls_perror (ret);
646           gnutls_deinit (hd.session);
647           return 1;
648         }
649       else
650         {
651           printf ("- Handshake was completed\n");
652           if (gnutls_session_is_resumed (hd.session) != 0)
653             printf ("*** This is a resumed session\n");
654         }
655
656
657
658       if (resume != 0 && i == 0)
659         {
660
661           gnutls_session_get_data (hd.session, NULL, &session_data_size);
662           session_data = malloc (session_data_size);
663
664           gnutls_session_get_data (hd.session, session_data,
665                                    &session_data_size);
666
667           gnutls_session_get_id (hd.session, NULL, &session_id_size);
668           session_id = malloc (session_id_size);
669           gnutls_session_get_id (hd.session, session_id, &session_id_size);
670
671           /* print some information */
672           print_info (hd.session, hostname, info.insecure);
673
674           printf ("- Disconnecting\n");
675           socket_bye (&hd);
676
677           printf
678             ("\n\n- Connecting again- trying to resume previous session\n");
679           socket_open (&hd, hostname, service);
680           socket_connect (&hd);
681         }
682       else
683         {
684           break;
685         }
686     }
687
688 after_handshake:
689
690   /* Warning!  Do not touch this text string, it is used by external
691      programs to search for when gnutls-cli has reached this point. */
692   printf ("\n- Simple Client Mode:\n\n");
693
694 #ifndef _WIN32
695   signal (SIGALRM, &starttls_alarm);
696 #endif
697
698   /* do not buffer */
699 #if !(defined _WIN32 || defined __WIN32__)
700   setbuf (stdin, NULL);
701 #endif
702   setbuf (stdout, NULL);
703   setbuf (stderr, NULL);
704
705   for (;;)
706     {
707       if (starttls_alarmed && !hd.secure)
708         {
709           /* Warning!  Do not touch this text string, it is used by
710              external programs to search for when gnutls-cli has
711              reached this point. */
712           fprintf (stderr, "*** Starting TLS handshake\n");
713           ret = do_handshake (&hd);
714           if (ret < 0)
715             {
716               fprintf (stderr, "*** Handshake has failed\n");
717               user_term = 1;
718               break;
719             }
720         }
721
722       FD_ZERO (&rset);
723       FD_SET (fileno (stdin), &rset);
724       FD_SET (hd.fd, &rset);
725
726       maxfd = MAX (fileno (stdin), hd.fd);
727       tv.tv_sec = 3;
728       tv.tv_usec = 0;
729
730       err = select (maxfd + 1, &rset, NULL, NULL, &tv);
731       if (err < 0)
732         continue;
733
734       if (FD_ISSET (hd.fd, &rset))
735         {
736           memset (buffer, 0, MAX_BUF + 1);
737           ret = socket_recv (&hd, buffer, MAX_BUF);
738
739           if (ret == 0)
740             {
741               printf ("- Peer has closed the GNUTLS connection\n");
742               break;
743             }
744           else if (handle_error (&hd, ret) < 0 && user_term == 0)
745             {
746               fprintf (stderr,
747                        "*** Server has terminated the connection abnormally.\n");
748               break;
749             }
750           else if (ret > 0)
751             {
752               if (verbose != 0)
753                 printf ("- Received[%d]: ", ret);
754               for (ii = 0; ii < ret; ii++)
755                 {
756                   fputc (buffer[ii], stdout);
757                 }
758               fflush (stdout);
759             }
760
761           if (user_term != 0)
762             break;
763         }
764
765       if (FD_ISSET (fileno (stdin), &rset))
766         {
767           if (fgets (buffer, MAX_BUF, stdin) == NULL)
768             {
769               if (hd.secure == 0)
770                 {
771                   /* Warning!  Do not touch this text string, it is
772                      used by external programs to search for when
773                      gnutls-cli has reached this point. */
774                   fprintf (stderr, "*** Starting TLS handshake\n");
775                   ret = do_handshake (&hd);
776                   clearerr (stdin);
777                   if (ret < 0)
778                     {
779                       fprintf (stderr, "*** Handshake has failed\n");
780                       user_term = 1;
781                       break;
782                     }
783                 }
784               else
785                 {
786                   user_term = 1;
787                   break;
788                 }
789               continue;
790             }
791
792           if (crlf != 0)
793             {
794               char *b = strchr (buffer, '\n');
795               if (b != NULL)
796                 strcpy (b, "\r\n");
797             }
798
799           ret = socket_send (&hd, buffer, strlen (buffer));
800
801           if (ret > 0)
802             {
803               if (verbose != 0)
804                 printf ("- Sent: %d bytes\n", ret);
805             }
806           else
807             handle_error (&hd, ret);
808
809         }
810     }
811
812   if (info.debug)
813     gcry_control (GCRYCTL_DUMP_RANDOM_STATS);
814
815   if (user_term != 0)
816     socket_bye (&hd);
817   else
818     gnutls_deinit (hd.session);
819
820 #ifdef ENABLE_SRP
821   if (srp_cred)
822     gnutls_srp_free_client_credentials (srp_cred);
823 #endif
824 #ifdef ENABLE_PSK
825   if (psk_cred)
826     gnutls_psk_free_client_credentials (psk_cred);
827 #endif
828
829   gnutls_certificate_free_credentials (xcred);
830
831 #ifdef ENABLE_ANON
832   gnutls_anon_free_client_credentials (anon_cred);
833 #endif
834
835   gnutls_global_deinit ();
836
837   return 0;
838 }
839
840 void
841 gaa_parser (int argc, char **argv)
842 {
843   if (gaa (argc, argv, &info) != -1)
844     {
845       fprintf (stderr,
846                "Error in the arguments. Use the --help or -h parameters to get more information.\n");
847       exit (1);
848     }
849
850   verbose = info.verbose;
851   disable_extensions = info.disable_extensions;
852   print_cert = info.print_cert;
853   starttls = info.starttls;
854   resume = info.resume;
855   insecure = info.insecure;
856   service = info.port;
857   record_max_size = info.record_size;
858   fingerprint = info.fingerprint;
859
860   if (info.fmtder == 0)
861     x509ctype = GNUTLS_X509_FMT_PEM;
862   else
863     x509ctype = GNUTLS_X509_FMT_DER;
864
865   srp_username = info.srp_username;
866   srp_passwd = info.srp_passwd;
867   x509_cafile = info.x509_cafile;
868   x509_crlfile = info.x509_crlfile;
869   x509_keyfile = info.x509_keyfile;
870   x509_certfile = info.x509_certfile;
871   pgp_keyfile = info.pgp_keyfile;
872   pgp_certfile = info.pgp_certfile;
873
874   psk_username = info.psk_username;
875   psk_key.data = (unsigned char *) info.psk_key;
876   if (info.psk_key != NULL)
877     psk_key.size = strlen (info.psk_key);
878   else
879     psk_key.size = 0;
880
881   pgp_keyring = info.pgp_keyring;
882
883   crlf = info.crlf;
884
885   if (info.rest_args == NULL)
886     hostname = "localhost";
887   else
888     hostname = info.rest_args;
889
890   parse_protocols (info.proto, info.nproto, protocol_priority);
891   parse_ciphers (info.ciphers, info.nciphers, cipher_priority);
892   parse_macs (info.macs, info.nmacs, mac_priority);
893   parse_ctypes (info.ctype, info.nctype, cert_type_priority);
894   parse_kx (info.kx, info.nkx, kx_priority);
895   parse_comp (info.comp, info.ncomp, comp_priority);
896 }
897
898 void cli_version (void);
899
900 void
901 cli_version (void)
902 {
903   const char *p = PACKAGE_NAME;
904   if (strcmp (gnutls_check_version (NULL), PACKAGE_VERSION) != 0)
905     p = PACKAGE_STRING;
906   version_etc (stdout, program_name, p, gnutls_check_version (NULL),
907                "Nikos Mavrogiannopoulos", (char *) NULL);
908 }
909
910
911 static void
912 check_rehandshake (socket_st * socket, int ret)
913 {
914   if (socket->secure && ret == GNUTLS_E_REHANDSHAKE)
915     {
916       /* There is a race condition here. If application
917        * data is sent after the rehandshake request,
918        * the server thinks we ignored his request.
919        * This is a bad design of this client.
920        */
921       printf ("*** Received rehandshake request\n");
922       /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
923
924       ret = do_handshake (socket);
925
926       if (ret == 0)
927         {
928           printf ("*** Rehandshake was performed.\n");
929         }
930       else
931         {
932           printf ("*** Rehandshake Failed.\n");
933         }
934     }
935 }
936
937
938 static int
939 do_handshake (socket_st * socket)
940 {
941   int ret;
942   gnutls_transport_set_ptr (socket->session,
943                             (gnutls_transport_ptr_t) socket->fd);
944   do
945     {
946       ret = gnutls_handshake (socket->session);
947
948       if (ret < 0)
949         {
950           handle_error (socket, ret);
951         }
952     }
953   while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
954
955   if (ret == 0)
956     {
957       /* print some information */
958       print_info (socket->session, socket->hostname, info.insecure);
959
960       if ((x509_cafile || pgp_keyring) && !insecure)
961         {
962           int rc;
963           unsigned int status;
964
965           /* abort if verification fail  */
966           rc = gnutls_certificate_verify_peers2 (socket->session, &status);
967           if (rc != 0 || status != 0)
968             {
969               printf ("*** Verifying server certificate failed...\n");
970               exit (1);
971             }
972         }
973
974       socket->secure = 1;
975
976     }
977   return ret;
978 }
979
980 static int
981 srp_username_callback (gnutls_session_t session,
982                        char **username, char **password)
983 {
984   if (srp_username == NULL || srp_passwd == NULL)
985     {
986       return -1;
987     }
988
989   *username = gnutls_strdup (srp_username);
990   *password = gnutls_strdup (srp_passwd);
991
992   return 0;
993 }
994
995 static int
996 psk_callback (gnutls_session_t session, char **username, gnutls_datum_t * key)
997 {
998   const char *hint = gnutls_psk_client_get_hint (session);
999   char *passwd;
1000   int ret;
1001
1002   printf ("- PSK client callback. ");
1003   if (hint)
1004     printf ("PSK hint '%s'\n", hint);
1005   else
1006     printf ("No PSK hint\n");
1007
1008   if (info.psk_username)
1009     *username = gnutls_strdup (info.psk_username);
1010   else
1011     {
1012       char *tmp = NULL;
1013       size_t n;
1014       ssize_t len;
1015
1016       printf ("Enter PSK identity: ");
1017       fflush (stdout);
1018       len = getline (&tmp, &n, stdin);
1019
1020       if (tmp == NULL)
1021         {
1022           fprintf (stderr, "No username given, aborting...\n");
1023           return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1024         }
1025
1026       if (tmp[strlen (tmp) - 1] == '\n')
1027         tmp[strlen (tmp) - 1] = '\0';
1028       if (tmp[strlen (tmp) - 1] == '\r')
1029         tmp[strlen (tmp) - 1] = '\0';
1030
1031       *username = gnutls_strdup (tmp);
1032       free (tmp);
1033     }
1034   if (!*username)
1035     return GNUTLS_E_MEMORY_ERROR;
1036
1037   passwd = getpass ("Enter password: ");
1038   if (passwd == NULL)
1039     {
1040       fprintf (stderr, "No password given, aborting...\n");
1041       return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1042     }
1043
1044   ret = gnutls_psk_netconf_derive_key (passwd,
1045                                        *username, hint ? hint : "", key);
1046   if (ret < 0)
1047     {
1048       fprintf (stderr, "Error deriving password: %s\n",
1049                gnutls_strerror (ret));
1050       gnutls_free (*username);
1051       return ret;
1052     }
1053
1054   if (info.debug)
1055     {
1056       char hexkey[41];
1057       size_t res_size = sizeof (hexkey);
1058       gnutls_hex_encode (key, hexkey, &res_size);
1059       fprintf (stderr, "PSK username: %s\n", *username);
1060       fprintf (stderr, "PSK hint: %s\n", hint);
1061       fprintf (stderr, "PSK key: %s\n", hexkey);
1062     }
1063
1064   return 0;
1065 }
1066
1067 static void
1068 init_global_tls_stuff (void)
1069 {
1070   int ret;
1071
1072   /* X509 stuff */
1073   if (gnutls_certificate_allocate_credentials (&xcred) < 0)
1074     {
1075       fprintf (stderr, "Certificate allocation memory error\n");
1076       exit (1);
1077     }
1078
1079   /* there are some CAs that have a v1 certificate *%&@#*%&
1080    */
1081   gnutls_certificate_set_verify_flags (xcred,
1082                                        GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
1083
1084   if (x509_cafile != NULL)
1085     {
1086       ret =
1087         gnutls_certificate_set_x509_trust_file (xcred,
1088                                                 x509_cafile, x509ctype);
1089       if (ret < 0)
1090         {
1091           fprintf (stderr, "Error setting the x509 trust file\n");
1092         }
1093       else
1094         {
1095           printf ("Processed %d CA certificate(s).\n", ret);
1096         }
1097     }
1098 #ifdef ENABLE_PKI
1099   if (x509_crlfile != NULL)
1100     {
1101       ret =
1102         gnutls_certificate_set_x509_crl_file (xcred, x509_crlfile, x509ctype);
1103       if (ret < 0)
1104         {
1105           fprintf (stderr, "Error setting the x509 CRL file\n");
1106         }
1107       else
1108         {
1109           printf ("Processed %d CRL(s).\n", ret);
1110         }
1111     }
1112 #endif
1113
1114   load_keys ();
1115
1116 #ifdef ENABLE_OPENPGP
1117   if (pgp_keyring != NULL)
1118     {
1119       ret =
1120         gnutls_certificate_set_openpgp_keyring_file (xcred, pgp_keyring,
1121                                                      GNUTLS_OPENPGP_FMT_BASE64);
1122       if (ret < 0)
1123         {
1124           fprintf (stderr, "Error setting the OpenPGP keyring file\n");
1125         }
1126     }
1127 #endif
1128
1129 #ifdef ENABLE_SRP
1130   if (srp_username && srp_passwd)
1131     {
1132       /* SRP stuff */
1133       if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0)
1134         {
1135           fprintf (stderr, "SRP authentication error\n");
1136         }
1137
1138       gnutls_srp_set_client_credentials_function (srp_cred,
1139                                                   srp_username_callback);
1140     }
1141 #endif
1142
1143 #ifdef ENABLE_PSK
1144   /* PSK stuff */
1145   if (gnutls_psk_allocate_client_credentials (&psk_cred) < 0)
1146     {
1147       fprintf (stderr, "PSK authentication error\n");
1148     }
1149
1150   if (psk_username && psk_key.data)
1151     {
1152       ret = gnutls_psk_set_client_credentials (psk_cred,
1153                                                psk_username, &psk_key,
1154                                                GNUTLS_PSK_KEY_HEX);
1155       if (ret < 0)
1156         {
1157           fprintf (stderr, "Error setting the PSK credentials: %s\n",
1158                    gnutls_strerror (ret));
1159         }
1160     }
1161   gnutls_psk_set_client_credentials_function (psk_cred, psk_callback);
1162 #endif
1163
1164 #ifdef ENABLE_ANON
1165   /* ANON stuff */
1166   if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
1167     {
1168       fprintf (stderr, "Anonymous authentication error\n");
1169     }
1170 #endif
1171
1172 }
1173
1174 /* Functions to manipulate sockets
1175  */
1176
1177 ssize_t
1178 socket_recv (const socket_st * socket, void *buffer, int buffer_size)
1179 {
1180   int ret;
1181
1182   if (socket->secure)
1183     do
1184       {
1185         ret = gnutls_record_recv (socket->session, buffer, buffer_size);
1186       }
1187     while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
1188   else
1189     do
1190       {
1191         ret = recv (socket->fd, buffer, buffer_size, 0);
1192       }
1193     while (ret == -1 && errno == EINTR);
1194
1195   return ret;
1196 }
1197
1198 ssize_t
1199 socket_send (const socket_st * socket, const void *buffer, int buffer_size)
1200 {
1201   int ret;
1202
1203   if (socket->secure)
1204     do
1205       {
1206         ret = gnutls_record_send (socket->session, buffer, buffer_size);
1207       }
1208     while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
1209   else
1210     do
1211       {
1212         ret = send (socket->fd, buffer, buffer_size, 0);
1213       }
1214     while (ret == -1 && errno == EINTR);
1215
1216   if (ret > 0 && ret != buffer_size && verbose)
1217     fprintf (stderr,
1218              "*** Only sent %d bytes instead of %d.\n", ret, buffer_size);
1219
1220   return ret;
1221 }
1222
1223 void
1224 socket_bye (socket_st * socket)
1225 {
1226   int ret;
1227   if (socket->secure)
1228     {
1229       do
1230         ret = gnutls_bye (socket->session, GNUTLS_SHUT_RDWR);
1231       while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
1232       if (ret < 0)
1233         fprintf (stderr, "*** gnutls_bye() error: %s\n",
1234                  gnutls_strerror (ret));
1235       gnutls_deinit (socket->session);
1236       socket->session = NULL;
1237     }
1238
1239   freeaddrinfo (socket->addr_info);
1240   socket->addr_info = socket->ptr = NULL;
1241
1242   free (socket->ip);
1243   free (socket->hostname);
1244   free (socket->service);
1245
1246   shutdown (socket->fd, SHUT_RDWR);     /* no more receptions */
1247   close (socket->fd);
1248
1249   socket->fd = -1;
1250   socket->secure = 0;
1251 }
1252
1253 void
1254 socket_connect (const socket_st * hd)
1255 {
1256   int err;
1257
1258   printf ("Connecting to '%s:%s'...\n", hd->ip, hd->service);
1259
1260   err = connect (hd->fd, hd->ptr->ai_addr, hd->ptr->ai_addrlen);
1261   if (err < 0)
1262     {
1263       fprintf (stderr, "Cannot connect to %s:%s: %s\n", hd->hostname,
1264                hd->service, strerror (errno));
1265       exit (1);
1266     }
1267 }
1268
1269 void
1270 socket_open (socket_st * hd, const char *hostname, const char *service)
1271 {
1272   struct addrinfo hints, *res, *ptr;
1273   int sd, err;
1274   char buffer[MAX_BUF + 1];
1275   char portname[16] = { 0 };
1276
1277   printf ("Resolving '%s'...\n", hostname);
1278   /* get server name */
1279   memset (&hints, 0, sizeof (hints));
1280   hints.ai_socktype = SOCK_STREAM;
1281   if ((err = getaddrinfo (hostname, service, &hints, &res)))
1282     {
1283       fprintf (stderr, "Cannot resolve %s:%s: %s\n", hostname, service,
1284                gai_strerror (err));
1285       exit (1);
1286     }
1287
1288   sd = -1;
1289   for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
1290     {
1291       sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
1292       if (sd == -1)
1293         continue;
1294
1295       if ((err = getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF,
1296                               portname, sizeof (portname),
1297                               NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1298         {
1299           fprintf (stderr, "getnameinfo(): %s\n", gai_strerror (err));
1300           freeaddrinfo (res);
1301           exit (1);
1302         }
1303
1304       break;
1305     }
1306
1307   if (sd == -1)
1308     {
1309       fprintf (stderr, "socket(): %s\n", strerror (errno));
1310       exit (1);
1311     }
1312
1313   hd->secure = 0;
1314   hd->fd = sd;
1315   hd->hostname = strdup (hostname);
1316   hd->ip = strdup (buffer);
1317   hd->service = strdup (portname);
1318   hd->ptr = ptr;
1319   hd->addr_info = res;
1320
1321   return;
1322 }