Fix dangling/unused bindings in `(gnutls)'.
[gnutls.git] / src / cli.c
blob1136d9d0e3b40a29d518bee02f1a701fdc8619e1
1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation
3 * Copyright (C) 2000,2001,2002,2003 Nikos Mavrogiannopoulos
5 * This file is part of GNUTLS.
7 * GNUTLS is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * GNUTLS is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <config.h>
23 #include <stdio.h>
24 #include <errno.h>
25 #include <stdlib.h>
26 #include <sys/types.h>
27 #include <string.h>
28 #include <sys/time.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31 #include <fcntl.h>
33 #include <gnutls/gnutls.h>
34 #include <gnutls/extra.h>
35 #include <gnutls/x509.h>
36 #include <gnutls/openpgp.h>
37 #include <gcrypt.h>
39 #include "error.h"
40 #include "read-file.h"
42 #include "common.h"
43 #include "cli-gaa.h"
45 #if defined _WIN32 || defined __WIN32__
46 #define select _win_select
47 #endif
49 #ifndef SHUT_WR
50 # define SHUT_WR 1
51 #endif
53 #ifndef SHUT_RDWR
54 # define SHUT_RDWR 2
55 #endif
57 #define SA struct sockaddr
58 #define ERR(err,s) do { if (err==-1) {perror(s);return(1);} } while (0)
59 #define MAX_BUF 4096
61 /* global stuff here */
62 int resume, starttls, insecure;
63 char *hostname = NULL;
64 char *service;
65 int record_max_size;
66 int fingerprint;
67 int crlf;
68 int verbose = 0;
69 extern int print_cert;
71 char *srp_passwd = NULL;
72 char *srp_username;
73 char *pgp_keyfile;
74 char *pgp_certfile;
75 char *pgp_keyring;
76 char *x509_keyfile;
77 char *x509_certfile;
78 char *x509_cafile;
79 char *x509_crlfile = NULL;
80 static int x509ctype;
81 static int disable_extensions;
83 char *psk_username = NULL;
84 gnutls_datum_t psk_key = { NULL, 0 };
86 static gnutls_srp_client_credentials_t srp_cred;
87 static gnutls_psk_client_credentials_t psk_cred;
88 static gnutls_anon_client_credentials_t anon_cred;
89 static gnutls_certificate_credentials_t xcred;
91 static gaainfo info;
93 static int protocol_priority[PRI_MAX];
94 static int kx_priority[PRI_MAX];
95 static int cipher_priority[PRI_MAX];
96 static int comp_priority[PRI_MAX];
97 static int mac_priority[PRI_MAX];
98 static int cert_type_priority[PRI_MAX];
100 /* end of global stuff */
102 /* prototypes */
103 typedef struct
105 int fd;
106 gnutls_session_t session;
107 int secure;
108 char *hostname;
109 char *ip;
110 char *service;
111 struct addrinfo *ptr;
112 struct addrinfo *addr_info;
113 } socket_st;
115 ssize_t socket_recv (const socket_st * socket, void *buffer, int buffer_size);
116 ssize_t socket_send (const socket_st * socket, const void *buffer,
117 int buffer_size);
118 void socket_open (socket_st * hd, const char *hostname, const char *service);
119 void socket_connect (const socket_st * hd);
120 void socket_bye (socket_st * socket);
122 static void check_rehandshake (socket_st * socket, int ret);
123 static int do_handshake (socket_st * socket);
124 static void init_global_tls_stuff (void);
127 #undef MAX
128 #define MAX(X,Y) (X >= Y ? X : Y);
131 /* Helper functions to load a certificate and key
132 * files into memory.
134 static gnutls_datum_t
135 load_file (const char *file)
137 FILE *f;
138 gnutls_datum_t loaded_file = { NULL, 0 };
139 long filelen;
140 void *ptr;
142 if (!(f = fopen (file, "r"))
143 || fseek (f, 0, SEEK_END) != 0
144 || (filelen = ftell (f)) < 0
145 || fseek (f, 0, SEEK_SET) != 0
146 || !(ptr = malloc ((size_t) filelen))
147 || fread (ptr, 1, (size_t) filelen, f) < (size_t) filelen)
149 return loaded_file;
152 loaded_file.data = ptr;
153 loaded_file.size = (unsigned int) filelen;
154 return loaded_file;
157 static void
158 unload_file (gnutls_datum_t data)
160 free (data.data);
163 #define MAX_CRT 6
164 static unsigned int x509_crt_size;
165 static gnutls_x509_crt_t x509_crt[MAX_CRT];
166 static gnutls_x509_privkey_t x509_key = NULL;
168 static gnutls_openpgp_crt_t pgp_crt = NULL;
169 static gnutls_openpgp_privkey_t pgp_key = NULL;
171 /* Load the certificate and the private key.
173 static void
174 load_keys (void)
176 unsigned int crt_num;
177 int ret;
178 gnutls_datum_t data;
180 if (x509_certfile != NULL && x509_keyfile != NULL)
182 data = load_file (x509_certfile);
183 if (data.data == NULL)
185 fprintf (stderr, "*** Error loading cert file.\n");
186 exit (1);
189 crt_num = MAX_CRT;
190 ret =
191 gnutls_x509_crt_list_import (x509_crt, &crt_num, &data,
192 GNUTLS_X509_FMT_PEM,
193 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
194 if (ret < 0)
196 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
198 fprintf (stderr,
199 "*** Error loading cert file: Too many certs %d\n",
200 crt_num);
203 else
205 fprintf (stderr,
206 "*** Error loading cert file: %s\n",
207 gnutls_strerror (ret));
209 exit (1);
211 x509_crt_size = ret;
212 fprintf (stderr, "Processed %d client certificates...\n", ret);
214 unload_file (data);
216 data = load_file (x509_keyfile);
217 if (data.data == NULL)
219 fprintf (stderr, "*** Error loading key file.\n");
220 exit (1);
223 gnutls_x509_privkey_init (&x509_key);
225 ret = gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM);
226 if (ret < 0)
228 fprintf (stderr, "*** Error loading key file: %s\n",
229 gnutls_strerror (ret));
230 exit (1);
233 unload_file (data);
235 fprintf (stderr, "Processed %d client X.509 certificates...\n",
236 x509_crt_size);
238 #ifdef ENABLE_OPENPGP
239 if (pgp_certfile != NULL && pgp_keyfile != NULL)
241 data = load_file (pgp_certfile);
242 if (data.data == NULL)
244 fprintf (stderr, "*** Error loading PGP cert file.\n");
245 exit (1);
247 gnutls_openpgp_crt_init (&pgp_crt);
249 ret =
250 gnutls_openpgp_crt_import (pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64);
251 if (ret < 0)
253 fprintf (stderr,
254 "*** Error loading PGP cert file: %s\n",
255 gnutls_strerror (ret));
256 exit (1);
259 unload_file (data);
261 data = load_file (pgp_keyfile);
262 if (data.data == NULL)
264 fprintf (stderr, "*** Error loading PGP key file.\n");
265 exit (1);
268 gnutls_openpgp_privkey_init (&pgp_key);
270 ret =
271 gnutls_openpgp_privkey_import (pgp_key, &data,
272 GNUTLS_OPENPGP_FMT_BASE64, NULL, 0);
273 if (ret < 0)
275 fprintf (stderr,
276 "*** Error loading PGP key file: %s\n",
277 gnutls_strerror (ret));
278 exit (1);
281 unload_file (data);
282 fprintf (stderr, "Processed 1 client PGP certificate...\n");
284 #endif
290 /* This callback should be associated with a session by calling
291 * gnutls_certificate_client_set_retrieve_function( session, cert_callback),
292 * before a handshake.
295 static int
296 cert_callback (gnutls_session_t session,
297 const gnutls_datum_t * req_ca_rdn, int nreqs,
298 const gnutls_pk_algorithm_t * sign_algos,
299 int sign_algos_length, gnutls_retr_st * st)
301 char issuer_dn[256];
302 int i, ret;
303 size_t len;
305 if (verbose)
308 /* Print the server's trusted CAs
310 if (nreqs > 0)
311 printf ("- Server's trusted authorities:\n");
312 else
313 printf ("- Server did not send us any trusted authorities names.\n");
315 /* print the names (if any) */
316 for (i = 0; i < nreqs; i++)
318 len = sizeof (issuer_dn);
319 ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len);
320 if (ret >= 0)
322 printf (" [%d]: ", i);
323 printf ("%s\n", issuer_dn);
328 /* Select a certificate and return it.
329 * The certificate must be of any of the "sign algorithms"
330 * supported by the server.
333 st->type = gnutls_certificate_type_get (session);
335 st->ncerts = 0;
337 if (st->type == GNUTLS_CRT_X509)
339 if (x509_crt != NULL && x509_key != NULL)
341 st->ncerts = x509_crt_size;
343 st->cert.x509 = x509_crt;
344 st->key.x509 = x509_key;
346 st->deinit_all = 0;
348 return 0;
351 else if (st->type == GNUTLS_CRT_OPENPGP)
353 if (pgp_key != NULL && pgp_crt != NULL)
355 st->ncerts = 1;
357 st->cert.pgp = pgp_crt;
358 st->key.pgp = pgp_key;
360 st->deinit_all = 0;
362 return 0;
366 printf ("- Successfully sent %d certificate(s) to server.\n", st->ncerts);
367 return 0;
371 /* initializes a gnutls_session_t with some defaults.
373 static gnutls_session_t
374 init_tls_session (const char *hostname)
376 const char *err;
378 gnutls_session_t session;
380 gnutls_init (&session, GNUTLS_CLIENT);
382 if (gnutls_priority_set_direct (session, info.priorities, &err) < 0)
384 fprintf(stderr, "Syntax error at: %s\n", err);
385 exit(1);
388 /* allow the use of private ciphersuites.
390 if (disable_extensions == 0)
392 gnutls_handshake_set_private_extensions (session, 1);
393 gnutls_server_name_set (session, GNUTLS_NAME_DNS, hostname,
394 strlen (hostname));
395 if (cert_type_priority[0])
396 gnutls_certificate_type_set_priority (session, cert_type_priority);
399 if (cipher_priority[0])
400 gnutls_cipher_set_priority (session, cipher_priority);
401 if (comp_priority[0])
402 gnutls_compression_set_priority (session, comp_priority);
403 if (kx_priority[0])
404 gnutls_kx_set_priority (session, kx_priority);
405 if (protocol_priority[0])
406 gnutls_protocol_set_priority (session, protocol_priority);
407 if (mac_priority[0])
408 gnutls_mac_set_priority (session, mac_priority);
410 gnutls_dh_set_prime_bits (session, 512);
412 gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred);
413 if (srp_cred)
414 gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred);
415 if (psk_cred)
416 gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred);
417 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
419 gnutls_certificate_client_set_retrieve_function (xcred, cert_callback);
421 /* send the fingerprint */
422 if (fingerprint != 0)
423 gnutls_openpgp_send_cert (session, GNUTLS_OPENPGP_CERT_FINGERPRINT);
425 /* use the max record size extension */
426 if (record_max_size > 0 && disable_extensions == 0)
428 if (gnutls_record_set_max_size (session, record_max_size) < 0)
430 fprintf (stderr,
431 "Cannot set the maximum record size to %d.\n",
432 record_max_size);
433 fprintf (stderr, "Possible values: 512, 1024, 2048, 4096.\n");
434 exit (1);
438 #ifdef ENABLE_OPRFI
439 if (info.opaque_prf_input)
440 gnutls_oprfi_enable_client (session, strlen (info.opaque_prf_input),
441 info.opaque_prf_input);
442 #endif
444 return session;
447 static void gaa_parser (int argc, char **argv);
449 /* Returns zero if the error code was successfully handled.
451 static int
452 handle_error (socket_st * hd, int err)
454 int alert, ret;
455 const char *err_type, *str;
457 if (err >= 0)
458 return 0;
460 if (gnutls_error_is_fatal (err) == 0)
462 ret = 0;
463 err_type = "Non fatal";
465 else
467 ret = err;
468 err_type = "Fatal";
471 str = gnutls_strerror (err);
472 if (str == NULL)
473 str = str_unknown;
474 fprintf (stderr, "*** %s error: %s\n", err_type, str);
476 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
477 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
479 alert = gnutls_alert_get (hd->session);
480 str = gnutls_alert_get_name (alert);
481 if (str == NULL)
482 str = str_unknown;
483 printf ("*** Received alert [%d]: %s\n", alert, str);
485 /* In SRP if the alert is MISSING_SRP_USERNAME,
486 * we should read the username/password and
487 * call gnutls_handshake(). This is not implemented
488 * here.
492 check_rehandshake (hd, ret);
494 return ret;
497 int starttls_alarmed = 0;
499 void
500 starttls_alarm (int signum)
502 starttls_alarmed = 1;
505 static void
506 tls_log_func (int level, const char *str)
508 fprintf (stderr, "|<%d>| %s", level, str);
512 main (int argc, char **argv)
514 int err, ret;
515 int ii, i;
516 char buffer[MAX_BUF + 1];
517 char *session_data = NULL;
518 char *session_id = NULL;
519 size_t session_data_size;
520 size_t session_id_size;
521 fd_set rset;
522 int maxfd;
523 struct timeval tv;
524 int user_term = 0;
525 socket_st hd;
527 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
529 if ((ret = gnutls_global_init ()) < 0)
531 fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
532 exit (1);
535 if ((ret = gnutls_global_init_extra ()) < 0)
537 fprintf (stderr, "global_init_extra: %s\n", gnutls_strerror (ret));
538 // exit (1);
541 gaa_parser (argc, argv);
542 if (hostname == NULL)
544 fprintf (stderr, "No hostname given\n");
545 exit (1);
548 gnutls_global_set_log_function (tls_log_func);
549 gnutls_global_set_log_level (info.debug);
551 sockets_init ();
553 #ifndef _WIN32
554 signal (SIGPIPE, SIG_IGN);
555 #endif
557 init_global_tls_stuff ();
559 socket_open (&hd, hostname, service);
560 socket_connect (&hd);
562 hd.session = init_tls_session (hostname);
563 if (starttls)
564 goto after_handshake;
566 for (i = 0; i < 2; i++)
570 if (i == 1)
572 hd.session = init_tls_session (hostname);
573 gnutls_session_set_data (hd.session, session_data,
574 session_data_size);
575 free (session_data);
578 ret = do_handshake (&hd);
580 if (ret < 0)
582 fprintf (stderr, "*** Handshake has failed\n");
583 gnutls_perror (ret);
584 gnutls_deinit (hd.session);
585 return 1;
587 else
589 printf ("- Handshake was completed\n");
590 if (gnutls_session_is_resumed (hd.session) != 0)
591 printf ("*** This is a resumed session\n");
596 if (resume != 0 && i == 0)
599 gnutls_session_get_data (hd.session, NULL, &session_data_size);
600 session_data = malloc (session_data_size);
602 gnutls_session_get_data (hd.session, session_data,
603 &session_data_size);
605 gnutls_session_get_id (hd.session, NULL, &session_id_size);
606 session_id = malloc (session_id_size);
607 gnutls_session_get_id (hd.session, session_id, &session_id_size);
609 /* print some information */
610 print_info (hd.session, hostname);
612 printf ("- Disconnecting\n");
613 socket_bye (&hd);
615 printf
616 ("\n\n- Connecting again- trying to resume previous session\n");
617 socket_open (&hd, hostname, service);
618 socket_connect (&hd);
620 else
622 break;
626 after_handshake:
628 /* Warning! Do not touch this text string, it is used by external
629 programs to search for when gnutls-cli has reached this point. */
630 printf ("\n- Simple Client Mode:\n\n");
632 #ifndef _WIN32
633 signal (SIGALRM, &starttls_alarm);
634 #endif
636 /* do not buffer */
637 #if !(defined _WIN32 || defined __WIN32__)
638 setbuf (stdin, NULL);
639 #endif
640 setbuf (stdout, NULL);
641 setbuf (stderr, NULL);
643 for (;;)
645 if (starttls_alarmed && !hd.secure)
647 /* Warning! Do not touch this text string, it is used by
648 external programs to search for when gnutls-cli has
649 reached this point. */
650 fprintf (stderr, "*** Starting TLS handshake\n");
651 ret = do_handshake (&hd);
652 if (ret < 0)
654 fprintf (stderr, "*** Handshake has failed\n");
655 socket_bye (&hd);
656 user_term = 1;
657 break;
661 FD_ZERO (&rset);
662 FD_SET (fileno (stdin), &rset);
663 FD_SET (hd.fd, &rset);
665 maxfd = MAX (fileno (stdin), hd.fd);
666 tv.tv_sec = 3;
667 tv.tv_usec = 0;
669 err = select (maxfd + 1, &rset, NULL, NULL, &tv);
670 if (err < 0)
671 continue;
673 if (FD_ISSET (hd.fd, &rset))
675 memset (buffer, 0, MAX_BUF + 1);
676 ret = socket_recv (&hd, buffer, MAX_BUF);
678 if (ret == 0)
680 printf ("- Peer has closed the GNUTLS connection\n");
681 break;
683 else if (handle_error (&hd, ret) < 0 && user_term == 0)
685 fprintf (stderr,
686 "*** Server has terminated the connection abnormally.\n");
687 break;
689 else if (ret > 0)
691 if (verbose != 0)
692 printf ("- Received[%d]: ", ret);
693 for (ii = 0; ii < ret; ii++)
695 fputc (buffer[ii], stdout);
697 fflush (stdout);
700 if (user_term != 0)
701 break;
704 if (FD_ISSET (fileno (stdin), &rset))
706 if (fgets (buffer, MAX_BUF, stdin) == NULL)
708 if (hd.secure == 0)
710 /* Warning! Do not touch this text string, it is
711 used by external programs to search for when
712 gnutls-cli has reached this point. */
713 fprintf (stderr, "*** Starting TLS handshake\n");
714 ret = do_handshake (&hd);
715 clearerr (stdin);
716 if (ret < 0)
718 fprintf (stderr, "*** Handshake has failed\n");
719 socket_bye (&hd);
720 user_term = 1;
721 break;
724 else
726 user_term = 1;
727 break;
729 continue;
732 if (crlf != 0)
734 char *b = strchr (buffer, '\n');
735 if (b != NULL)
736 strcpy (b, "\r\n");
739 ret = socket_send (&hd, buffer, strlen (buffer));
741 if (ret > 0)
743 if (verbose != 0)
744 printf ("- Sent: %d bytes\n", ret);
746 else
747 handle_error (&hd, ret);
752 if (user_term != 0)
753 socket_bye (&hd);
754 else
755 gnutls_deinit (hd.session);
757 #ifdef ENABLE_SRP
758 if (srp_cred)
759 gnutls_srp_free_client_credentials (srp_cred);
760 #endif
761 #ifdef ENABLE_PSK
762 if (psk_cred)
763 gnutls_psk_free_client_credentials (psk_cred);
764 #endif
766 gnutls_certificate_free_credentials (xcred);
768 #ifdef ENABLE_ANON
769 gnutls_anon_free_client_credentials (anon_cred);
770 #endif
772 gnutls_global_deinit ();
774 return 0;
777 void
778 gaa_parser (int argc, char **argv)
780 if (gaa (argc, argv, &info) != -1)
782 fprintf (stderr,
783 "Error in the arguments. Use the --help or -h parameters to get more information.\n");
784 exit (1);
787 verbose = info.verbose;
788 disable_extensions = info.disable_extensions;
789 print_cert = info.print_cert;
790 starttls = info.starttls;
791 resume = info.resume;
792 insecure = info.insecure;
793 service = info.port;
794 record_max_size = info.record_size;
795 fingerprint = info.fingerprint;
797 if (info.fmtder == 0)
798 x509ctype = GNUTLS_X509_FMT_PEM;
799 else
800 x509ctype = GNUTLS_X509_FMT_DER;
802 srp_username = info.srp_username;
803 srp_passwd = info.srp_passwd;
804 x509_cafile = info.x509_cafile;
805 x509_crlfile = info.x509_crlfile;
806 x509_keyfile = info.x509_keyfile;
807 x509_certfile = info.x509_certfile;
808 pgp_keyfile = info.pgp_keyfile;
809 pgp_certfile = info.pgp_certfile;
811 psk_username = info.psk_username;
812 psk_key.data = (unsigned char *) info.psk_key;
813 if (info.psk_key != NULL)
814 psk_key.size = strlen (info.psk_key);
815 else
816 psk_key.size = 0;
818 pgp_keyring = info.pgp_keyring;
820 crlf = info.crlf;
822 if (info.rest_args == NULL)
823 hostname = "localhost";
824 else
825 hostname = info.rest_args;
827 parse_protocols (info.proto, info.nproto, protocol_priority);
828 parse_ciphers (info.ciphers, info.nciphers, cipher_priority);
829 parse_macs (info.macs, info.nmacs, mac_priority);
830 parse_ctypes (info.ctype, info.nctype, cert_type_priority);
831 parse_kx (info.kx, info.nkx, kx_priority);
832 parse_comp (info.comp, info.ncomp, comp_priority);
835 void
836 cli_version (void)
838 const char *v = gnutls_check_version (NULL);
840 printf ("gnutls-cli (GnuTLS) %s\n", LIBGNUTLS_VERSION);
841 if (strcmp (v, LIBGNUTLS_VERSION) != 0)
842 printf ("libgnutls %s\n", v);
846 static void
847 check_rehandshake (socket_st * socket, int ret)
849 if (socket->secure && ret == GNUTLS_E_REHANDSHAKE)
851 /* There is a race condition here. If application
852 * data is sent after the rehandshake request,
853 * the server thinks we ignored his request.
854 * This is a bad design of this client.
856 printf ("*** Received rehandshake request\n");
857 /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
859 ret = do_handshake (socket);
861 if (ret == 0)
863 printf ("*** Rehandshake was performed.\n");
865 else
867 printf ("*** Rehandshake Failed.\n");
873 static int
874 do_handshake (socket_st * socket)
876 int ret;
877 gnutls_transport_set_ptr (socket->session,
878 (gnutls_transport_ptr_t) socket->fd);
881 ret = gnutls_handshake (socket->session);
883 if (ret < 0)
885 handle_error (socket, ret);
888 while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
890 if (ret == 0)
892 /* print some information */
893 print_info (socket->session, socket->hostname);
895 if ((x509_cafile || pgp_keyring) && !insecure)
897 int rc;
898 unsigned int status;
900 /* abort if verification fail */
901 rc = gnutls_certificate_verify_peers2 (socket->session, &status);
902 if (rc != 0 || status != 0)
904 printf ("*** Verifying server certificate failed...\n");
905 exit (1);
909 socket->secure = 1;
912 return ret;
915 static int
916 srp_username_callback (gnutls_session_t session,
917 char **username, char **password)
919 if (srp_username == NULL || srp_passwd == NULL)
921 return -1;
924 *username = gnutls_strdup (srp_username);
925 *password = gnutls_strdup (srp_passwd);
927 return 0;
930 static void
931 init_global_tls_stuff (void)
933 int ret;
935 /* X509 stuff */
936 if (gnutls_certificate_allocate_credentials (&xcred) < 0)
938 fprintf (stderr, "Certificate allocation memory error\n");
939 exit (1);
942 /* there are some CAs that have a v1 certificate *%&@#*%&
944 gnutls_certificate_set_verify_flags (xcred,
945 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
947 if (x509_cafile != NULL)
949 ret =
950 gnutls_certificate_set_x509_trust_file (xcred,
951 x509_cafile, x509ctype);
952 if (ret < 0)
954 fprintf (stderr, "Error setting the x509 trust file\n");
956 else
958 printf ("Processed %d CA certificate(s).\n", ret);
961 #ifdef ENABLE_PKI
962 if (x509_crlfile != NULL)
964 ret =
965 gnutls_certificate_set_x509_crl_file (xcred, x509_crlfile, x509ctype);
966 if (ret < 0)
968 fprintf (stderr, "Error setting the x509 CRL file\n");
970 else
972 printf ("Processed %d CRL(s).\n", ret);
975 #endif
977 load_keys ();
979 #ifdef ENABLE_OPENPGP
980 if (pgp_keyring != NULL)
982 ret = gnutls_certificate_set_openpgp_keyring_file (xcred, pgp_keyring, GNUTLS_OPENPGP_FMT_BASE64);
983 if (ret < 0)
985 fprintf (stderr, "Error setting the OpenPGP keyring file\n");
988 #endif
990 #ifdef ENABLE_SRP
991 if (srp_username && srp_passwd)
993 /* SRP stuff */
994 if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0)
996 fprintf (stderr, "SRP authentication error\n");
999 gnutls_srp_set_client_credentials_function (srp_cred,
1000 srp_username_callback);
1002 #endif
1004 #ifdef ENABLE_PSK
1005 if (psk_username && !psk_key.data)
1007 /* SRP stuff */
1008 if (gnutls_psk_allocate_client_credentials (&psk_cred) < 0)
1010 fprintf (stderr, "PSK authentication error\n");
1013 gnutls_psk_set_client_credentials (psk_cred,
1014 psk_username, &psk_key,
1015 GNUTLS_PSK_KEY_HEX);
1017 #endif
1019 #ifdef ENABLE_ANON
1020 /* ANON stuff */
1021 if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
1023 fprintf (stderr, "Anonymous authentication error\n");
1025 #endif
1029 /* Functions to manipulate sockets
1032 ssize_t
1033 socket_recv (const socket_st * socket, void *buffer, int buffer_size)
1035 int ret;
1037 if (socket->secure)
1040 ret = gnutls_record_recv (socket->session, buffer, buffer_size);
1042 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
1043 else
1046 ret = recv (socket->fd, buffer, buffer_size, 0);
1048 while (ret == -1 && errno == EINTR);
1050 return ret;
1053 ssize_t
1054 socket_send (const socket_st * socket, const void *buffer, int buffer_size)
1056 int ret;
1058 if (socket->secure)
1061 ret = gnutls_record_send (socket->session, buffer, buffer_size);
1063 while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
1064 else
1067 ret = send (socket->fd, buffer, buffer_size, 0);
1069 while (ret == -1 && errno == EINTR);
1071 if (ret > 0 && ret != buffer_size && verbose)
1072 fprintf (stderr,
1073 "*** Only sent %d bytes instead of %d.\n", ret, buffer_size);
1075 return ret;
1078 void
1079 socket_bye (socket_st * socket)
1081 int ret;
1082 if (socket->secure)
1085 ret = gnutls_bye (socket->session, GNUTLS_SHUT_RDWR);
1086 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
1087 if (ret < 0)
1088 fprintf (stderr, "*** gnutls_bye() error: %s\n",
1089 gnutls_strerror (ret));
1090 gnutls_deinit (socket->session);
1091 socket->session = NULL;
1094 freeaddrinfo (socket->addr_info);
1095 socket->addr_info = socket->ptr = NULL;
1097 free (socket->ip);
1098 free (socket->hostname);
1099 free (socket->service);
1101 shutdown (socket->fd, SHUT_RDWR); /* no more receptions */
1102 close (socket->fd);
1104 socket->fd = -1;
1105 socket->secure = 0;
1108 void
1109 socket_connect (const socket_st * hd)
1111 int err;
1113 printf ("Connecting to '%s:%s'...\n", hd->ip, hd->service);
1115 err = connect (hd->fd, hd->ptr->ai_addr, hd->ptr->ai_addrlen);
1116 if (err < 0)
1118 fprintf (stderr, "Cannot connect to %s:%s: %s\n", hd->hostname,
1119 hd->service, strerror (errno));
1120 exit (1);
1124 void
1125 socket_open (socket_st * hd, const char *hostname, const char *service)
1127 struct addrinfo hints, *res, *ptr;
1128 int sd, err;
1129 char buffer[MAX_BUF + 1];
1130 char portname[16] = { 0 };
1132 printf ("Resolving '%s'...\n", hostname);
1133 /* get server name */
1134 memset (&hints, 0, sizeof (hints));
1135 hints.ai_socktype = SOCK_STREAM;
1136 if ((err = getaddrinfo (hostname, service, &hints, &res)))
1138 fprintf (stderr, "Cannot resolve %s:%s: %s\n", hostname, service,
1139 gai_strerror (err));
1140 exit (1);
1143 sd = -1;
1144 for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
1146 sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
1147 if (sd == -1)
1148 continue;
1150 if ((err = getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF,
1151 portname, sizeof (portname),
1152 NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1154 fprintf (stderr, "getnameinfo(): %s\n", gai_strerror (err));
1155 freeaddrinfo (res);
1156 exit (1);
1159 break;
1162 if (sd == -1)
1164 fprintf (stderr, "socket(): %s\n", strerror (errno));
1165 exit (1);
1168 hd->secure = 0;
1169 hd->fd = sd;
1170 hd->hostname = strdup (hostname);
1171 hd->ip = strdup (buffer);
1172 hd->service = strdup (portname);
1173 hd->ptr = ptr;
1174 hd->addr_info = res;
1176 return;