2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation
3 * Copyright (C) 2000,2001,2002,2003 Nikos Mavrogiannopoulos
5 * This file is part of GNUTLS.
7 * GNUTLS is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * GNUTLS is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include <sys/types.h>
30 #include <sys/socket.h>
34 #include <gnutls/gnutls.h>
35 #include <gnutls/extra.h>
36 #include <gnutls/x509.h>
37 #include <gnutls/openpgp.h>
41 #include "read-file.h"
46 #if defined _WIN32 || defined __WIN32__
47 int _win_select(int max_fd
, fd_set
* rfds
, fd_set
* wfds
, fd_set
* efds
,
48 const struct timeval
*tv
);
49 #define select _win_select
52 #define SA struct sockaddr
53 #define ERR(err,s) do { if (err==-1) {perror(s);return(1);} } while (0)
56 /* global stuff here */
57 int resume
, starttls
, insecure
;
58 char *hostname
= NULL
;
64 extern int print_cert
;
66 char *srp_passwd
= NULL
;
74 char *x509_crlfile
= NULL
;
76 static int disable_extensions
;
78 char *psk_username
= NULL
;
79 gnutls_datum_t psk_key
= { NULL
, 0 };
81 static gnutls_srp_client_credentials_t srp_cred
;
82 static gnutls_psk_client_credentials_t psk_cred
;
83 static gnutls_anon_client_credentials_t anon_cred
;
84 static gnutls_certificate_credentials_t xcred
;
88 static int protocol_priority
[PRI_MAX
];
89 static int kx_priority
[PRI_MAX
];
90 static int cipher_priority
[PRI_MAX
];
91 static int comp_priority
[PRI_MAX
];
92 static int mac_priority
[PRI_MAX
];
93 static int cert_type_priority
[PRI_MAX
];
95 /* end of global stuff */
101 gnutls_session_t session
;
106 struct addrinfo
*ptr
;
107 struct addrinfo
*addr_info
;
110 ssize_t
socket_recv (const socket_st
* socket
, void *buffer
, int buffer_size
);
111 ssize_t
socket_send (const socket_st
* socket
, const void *buffer
,
113 void socket_open (socket_st
* hd
, const char *hostname
, const char *service
);
114 void socket_connect (const socket_st
* hd
);
115 void socket_bye (socket_st
* socket
);
117 static void check_rehandshake (socket_st
* socket
, int ret
);
118 static int do_handshake (socket_st
* socket
);
119 static void init_global_tls_stuff (void);
123 #define MAX(X,Y) (X >= Y ? X : Y);
126 /* Helper functions to load a certificate and key
129 static gnutls_datum_t
130 load_file (const char *file
)
133 gnutls_datum_t loaded_file
= { NULL
, 0 };
137 if (!(f
= fopen (file
, "r"))
138 || fseek (f
, 0, SEEK_END
) != 0
139 || (filelen
= ftell (f
)) < 0
140 || fseek (f
, 0, SEEK_SET
) != 0
141 || !(ptr
= malloc ((size_t) filelen
))
142 || fread (ptr
, 1, (size_t) filelen
, f
) < (size_t) filelen
)
147 loaded_file
.data
= ptr
;
148 loaded_file
.size
= (unsigned int) filelen
;
153 unload_file (gnutls_datum_t data
)
159 static unsigned int x509_crt_size
;
160 static gnutls_x509_crt_t x509_crt
[MAX_CRT
];
161 static gnutls_x509_privkey_t x509_key
= NULL
;
163 static gnutls_openpgp_crt_t pgp_crt
= NULL
;
164 static gnutls_openpgp_privkey_t pgp_key
= NULL
;
166 static void get_keyid( gnutls_openpgp_keyid_t keyid
, const char* str
)
168 size_t keyid_size
= sizeof(keyid
);
170 if (strlen(str
) != 16)
172 fprintf(stderr
, "The OpenPGP subkey ID has to be 16 hexadecimal characters.\n");
176 if (gnutls_hex2bin (str
, strlen(str
), keyid
, &keyid_size
) < 0)
178 fprintf(stderr
, "Error converting hex string: %s.\n", str
);
185 /* Load the certificate and the private key.
190 unsigned int crt_num
;
194 if (x509_certfile
!= NULL
&& x509_keyfile
!= NULL
)
196 data
= load_file (x509_certfile
);
197 if (data
.data
== NULL
)
199 fprintf (stderr
, "*** Error loading cert file.\n");
205 gnutls_x509_crt_list_import (x509_crt
, &crt_num
, &data
,
207 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED
);
210 if (ret
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
213 "*** Error loading cert file: Too many certs %d\n",
220 "*** Error loading cert file: %s\n",
221 gnutls_strerror (ret
));
226 fprintf (stderr
, "Processed %d client certificates...\n", ret
);
230 data
= load_file (x509_keyfile
);
231 if (data
.data
== NULL
)
233 fprintf (stderr
, "*** Error loading key file.\n");
237 gnutls_x509_privkey_init (&x509_key
);
239 ret
= gnutls_x509_privkey_import (x509_key
, &data
, GNUTLS_X509_FMT_PEM
);
242 fprintf (stderr
, "*** Error loading key file: %s\n",
243 gnutls_strerror (ret
));
249 fprintf (stderr
, "Processed %d client X.509 certificates...\n",
252 #ifdef ENABLE_OPENPGP
253 if (pgp_certfile
!= NULL
&& pgp_keyfile
!= NULL
)
255 data
= load_file (pgp_certfile
);
256 if (data
.data
== NULL
)
258 fprintf (stderr
, "*** Error loading PGP cert file.\n");
261 gnutls_openpgp_crt_init (&pgp_crt
);
264 gnutls_openpgp_crt_import (pgp_crt
, &data
, GNUTLS_OPENPGP_FMT_BASE64
);
268 "*** Error loading PGP cert file: %s\n",
269 gnutls_strerror (ret
));
276 data
= load_file (pgp_keyfile
);
277 if (data
.data
== NULL
)
279 fprintf (stderr
, "*** Error loading PGP key file.\n");
283 gnutls_openpgp_privkey_init (&pgp_key
);
286 gnutls_openpgp_privkey_import (pgp_key
, &data
,
287 GNUTLS_OPENPGP_FMT_BASE64
, NULL
, 0);
291 "*** Error loading PGP key file: %s\n",
292 gnutls_strerror (ret
));
298 if (info
.pgp_subkey
!= NULL
)
300 gnutls_openpgp_keyid_t keyid
;
302 if (strcasecmp(info
.pgp_subkey
, "auto")==0)
304 ret
= gnutls_openpgp_crt_get_auth_subkey( pgp_crt
, keyid
, 1);
308 "*** Error setting preferred sub key id (%s): %s\n", info
.pgp_subkey
,
309 gnutls_strerror (ret
));
314 get_keyid( keyid
, info
.pgp_subkey
);
316 ret
= gnutls_openpgp_crt_set_preferred_key_id( pgp_crt
, keyid
);
318 ret
= gnutls_openpgp_privkey_set_preferred_key_id( pgp_key
, keyid
);
322 "*** Error setting preferred sub key id (%s): %s\n", info
.pgp_subkey
,
323 gnutls_strerror (ret
));
328 fprintf (stderr
, "Processed 1 client PGP certificate...\n");
336 /* This callback should be associated with a session by calling
337 * gnutls_certificate_client_set_retrieve_function( session, cert_callback),
338 * before a handshake.
342 cert_callback (gnutls_session_t session
,
343 const gnutls_datum_t
* req_ca_rdn
, int nreqs
,
344 const gnutls_pk_algorithm_t
* sign_algos
,
345 int sign_algos_length
, gnutls_retr_st
* st
)
354 /* Print the server's trusted CAs
357 printf ("- Server's trusted authorities:\n");
359 printf ("- Server did not send us any trusted authorities names.\n");
361 /* print the names (if any) */
362 for (i
= 0; i
< nreqs
; i
++)
364 len
= sizeof (issuer_dn
);
365 ret
= gnutls_x509_rdn_get (&req_ca_rdn
[i
], issuer_dn
, &len
);
368 printf (" [%d]: ", i
);
369 printf ("%s\n", issuer_dn
);
374 /* Select a certificate and return it.
375 * The certificate must be of any of the "sign algorithms"
376 * supported by the server.
379 st
->type
= gnutls_certificate_type_get (session
);
383 if (st
->type
== GNUTLS_CRT_X509
)
385 if (x509_crt
!= NULL
&& x509_key
!= NULL
)
387 st
->ncerts
= x509_crt_size
;
389 st
->cert
.x509
= x509_crt
;
390 st
->key
.x509
= x509_key
;
397 else if (st
->type
== GNUTLS_CRT_OPENPGP
)
399 if (pgp_key
!= NULL
&& pgp_crt
!= NULL
)
403 st
->cert
.pgp
= pgp_crt
;
404 st
->key
.pgp
= pgp_key
;
412 printf ("- Successfully sent %d certificate(s) to server.\n", st
->ncerts
);
417 /* initializes a gnutls_session_t with some defaults.
419 static gnutls_session_t
420 init_tls_session (const char *hostname
)
424 gnutls_session_t session
;
426 gnutls_init (&session
, GNUTLS_CLIENT
);
428 if (gnutls_priority_set_direct (session
, info
.priorities
, &err
) < 0)
430 fprintf(stderr
, "Syntax error at: %s\n", err
);
434 /* allow the use of private ciphersuites.
436 if (disable_extensions
== 0)
438 gnutls_handshake_set_private_extensions (session
, 1);
439 gnutls_server_name_set (session
, GNUTLS_NAME_DNS
, hostname
,
441 if (cert_type_priority
[0])
442 gnutls_certificate_type_set_priority (session
, cert_type_priority
);
445 if (cipher_priority
[0])
446 gnutls_cipher_set_priority (session
, cipher_priority
);
447 if (comp_priority
[0])
448 gnutls_compression_set_priority (session
, comp_priority
);
450 gnutls_kx_set_priority (session
, kx_priority
);
451 if (protocol_priority
[0])
452 gnutls_protocol_set_priority (session
, protocol_priority
);
454 gnutls_mac_set_priority (session
, mac_priority
);
456 gnutls_dh_set_prime_bits (session
, 512);
458 gnutls_credentials_set (session
, GNUTLS_CRD_ANON
, anon_cred
);
460 gnutls_credentials_set (session
, GNUTLS_CRD_SRP
, srp_cred
);
462 gnutls_credentials_set (session
, GNUTLS_CRD_PSK
, psk_cred
);
463 gnutls_credentials_set (session
, GNUTLS_CRD_CERTIFICATE
, xcred
);
465 gnutls_certificate_client_set_retrieve_function (xcred
, cert_callback
);
467 /* send the fingerprint */
468 #ifdef ENABLE_OPENPGP
469 if (fingerprint
!= 0)
470 gnutls_openpgp_send_cert (session
, GNUTLS_OPENPGP_CERT_FINGERPRINT
);
473 /* use the max record size extension */
474 if (record_max_size
> 0 && disable_extensions
== 0)
476 if (gnutls_record_set_max_size (session
, record_max_size
) < 0)
479 "Cannot set the maximum record size to %d.\n",
481 fprintf (stderr
, "Possible values: 512, 1024, 2048, 4096.\n");
487 if (info
.opaque_prf_input
)
488 gnutls_oprfi_enable_client (session
, strlen (info
.opaque_prf_input
),
489 info
.opaque_prf_input
);
495 static void gaa_parser (int argc
, char **argv
);
497 /* Returns zero if the error code was successfully handled.
500 handle_error (socket_st
* hd
, int err
)
503 const char *err_type
, *str
;
508 if (gnutls_error_is_fatal (err
) == 0)
511 err_type
= "Non fatal";
519 str
= gnutls_strerror (err
);
522 fprintf (stderr
, "*** %s error: %s\n", err_type
, str
);
524 if (err
== GNUTLS_E_WARNING_ALERT_RECEIVED
525 || err
== GNUTLS_E_FATAL_ALERT_RECEIVED
)
527 alert
= gnutls_alert_get (hd
->session
);
528 str
= gnutls_alert_get_name (alert
);
531 printf ("*** Received alert [%d]: %s\n", alert
, str
);
533 /* In SRP if the alert is MISSING_SRP_USERNAME,
534 * we should read the username/password and
535 * call gnutls_handshake(). This is not implemented
540 check_rehandshake (hd
, ret
);
545 int starttls_alarmed
= 0;
548 starttls_alarm (int signum
)
550 starttls_alarmed
= 1;
554 tls_log_func (int level
, const char *str
)
556 fprintf (stderr
, "|<%d>| %s", level
, str
);
560 main (int argc
, char **argv
)
564 char buffer
[MAX_BUF
+ 1];
565 char *session_data
= NULL
;
566 char *session_id
= NULL
;
567 size_t session_data_size
;
568 size_t session_id_size
;
575 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM
, 0);
577 if ((ret
= gnutls_global_init ()) < 0)
579 fprintf (stderr
, "global_init: %s\n", gnutls_strerror (ret
));
583 gaa_parser (argc
, argv
);
584 if (hostname
== NULL
)
586 fprintf (stderr
, "No hostname given\n");
590 gnutls_global_set_log_function (tls_log_func
);
591 gnutls_global_set_log_level (info
.debug
);
596 signal (SIGPIPE
, SIG_IGN
);
599 init_global_tls_stuff ();
601 socket_open (&hd
, hostname
, service
);
602 socket_connect (&hd
);
604 hd
.session
= init_tls_session (hostname
);
606 goto after_handshake
;
608 for (i
= 0; i
< 2; i
++)
614 hd
.session
= init_tls_session (hostname
);
615 gnutls_session_set_data (hd
.session
, session_data
,
620 ret
= do_handshake (&hd
);
624 fprintf (stderr
, "*** Handshake has failed\n");
626 gnutls_deinit (hd
.session
);
631 printf ("- Handshake was completed\n");
632 if (gnutls_session_is_resumed (hd
.session
) != 0)
633 printf ("*** This is a resumed session\n");
638 if (resume
!= 0 && i
== 0)
641 gnutls_session_get_data (hd
.session
, NULL
, &session_data_size
);
642 session_data
= malloc (session_data_size
);
644 gnutls_session_get_data (hd
.session
, session_data
,
647 gnutls_session_get_id (hd
.session
, NULL
, &session_id_size
);
648 session_id
= malloc (session_id_size
);
649 gnutls_session_get_id (hd
.session
, session_id
, &session_id_size
);
651 /* print some information */
652 print_info (hd
.session
, hostname
, info
.insecure
);
654 printf ("- Disconnecting\n");
658 ("\n\n- Connecting again- trying to resume previous session\n");
659 socket_open (&hd
, hostname
, service
);
660 socket_connect (&hd
);
670 /* Warning! Do not touch this text string, it is used by external
671 programs to search for when gnutls-cli has reached this point. */
672 printf ("\n- Simple Client Mode:\n\n");
675 signal (SIGALRM
, &starttls_alarm
);
679 #if !(defined _WIN32 || defined __WIN32__)
680 setbuf (stdin
, NULL
);
682 setbuf (stdout
, NULL
);
683 setbuf (stderr
, NULL
);
687 if (starttls_alarmed
&& !hd
.secure
)
689 /* Warning! Do not touch this text string, it is used by
690 external programs to search for when gnutls-cli has
691 reached this point. */
692 fprintf (stderr
, "*** Starting TLS handshake\n");
693 ret
= do_handshake (&hd
);
696 fprintf (stderr
, "*** Handshake has failed\n");
703 FD_SET (fileno (stdin
), &rset
);
704 FD_SET (hd
.fd
, &rset
);
706 maxfd
= MAX (fileno (stdin
), hd
.fd
);
710 err
= select (maxfd
+ 1, &rset
, NULL
, NULL
, &tv
);
714 if (FD_ISSET (hd
.fd
, &rset
))
716 memset (buffer
, 0, MAX_BUF
+ 1);
717 ret
= socket_recv (&hd
, buffer
, MAX_BUF
);
721 printf ("- Peer has closed the GNUTLS connection\n");
724 else if (handle_error (&hd
, ret
) < 0 && user_term
== 0)
727 "*** Server has terminated the connection abnormally.\n");
733 printf ("- Received[%d]: ", ret
);
734 for (ii
= 0; ii
< ret
; ii
++)
736 fputc (buffer
[ii
], stdout
);
745 if (FD_ISSET (fileno (stdin
), &rset
))
747 if (fgets (buffer
, MAX_BUF
, stdin
) == NULL
)
751 /* Warning! Do not touch this text string, it is
752 used by external programs to search for when
753 gnutls-cli has reached this point. */
754 fprintf (stderr
, "*** Starting TLS handshake\n");
755 ret
= do_handshake (&hd
);
759 fprintf (stderr
, "*** Handshake has failed\n");
774 char *b
= strchr (buffer
, '\n');
779 ret
= socket_send (&hd
, buffer
, strlen (buffer
));
784 printf ("- Sent: %d bytes\n", ret
);
787 handle_error (&hd
, ret
);
793 gcry_control (GCRYCTL_DUMP_RANDOM_STATS
);
798 gnutls_deinit (hd
.session
);
802 gnutls_srp_free_client_credentials (srp_cred
);
806 gnutls_psk_free_client_credentials (psk_cred
);
809 gnutls_certificate_free_credentials (xcred
);
812 gnutls_anon_free_client_credentials (anon_cred
);
815 gnutls_global_deinit ();
821 gaa_parser (int argc
, char **argv
)
823 if (gaa (argc
, argv
, &info
) != -1)
826 "Error in the arguments. Use the --help or -h parameters to get more information.\n");
830 verbose
= info
.verbose
;
831 disable_extensions
= info
.disable_extensions
;
832 print_cert
= info
.print_cert
;
833 starttls
= info
.starttls
;
834 resume
= info
.resume
;
835 insecure
= info
.insecure
;
837 record_max_size
= info
.record_size
;
838 fingerprint
= info
.fingerprint
;
840 if (info
.fmtder
== 0)
841 x509ctype
= GNUTLS_X509_FMT_PEM
;
843 x509ctype
= GNUTLS_X509_FMT_DER
;
845 srp_username
= info
.srp_username
;
846 srp_passwd
= info
.srp_passwd
;
847 x509_cafile
= info
.x509_cafile
;
848 x509_crlfile
= info
.x509_crlfile
;
849 x509_keyfile
= info
.x509_keyfile
;
850 x509_certfile
= info
.x509_certfile
;
851 pgp_keyfile
= info
.pgp_keyfile
;
852 pgp_certfile
= info
.pgp_certfile
;
854 psk_username
= info
.psk_username
;
855 psk_key
.data
= (unsigned char *) info
.psk_key
;
856 if (info
.psk_key
!= NULL
)
857 psk_key
.size
= strlen (info
.psk_key
);
861 pgp_keyring
= info
.pgp_keyring
;
865 if (info
.rest_args
== NULL
)
866 hostname
= "localhost";
868 hostname
= info
.rest_args
;
870 parse_protocols (info
.proto
, info
.nproto
, protocol_priority
);
871 parse_ciphers (info
.ciphers
, info
.nciphers
, cipher_priority
);
872 parse_macs (info
.macs
, info
.nmacs
, mac_priority
);
873 parse_ctypes (info
.ctype
, info
.nctype
, cert_type_priority
);
874 parse_kx (info
.kx
, info
.nkx
, kx_priority
);
875 parse_comp (info
.comp
, info
.ncomp
, comp_priority
);
881 const char *v
= gnutls_check_version (NULL
);
883 printf ("gnutls-cli (GnuTLS) %s\n", LIBGNUTLS_VERSION
);
884 if (strcmp (v
, LIBGNUTLS_VERSION
) != 0)
885 printf ("libgnutls %s\n", v
);
890 check_rehandshake (socket_st
* socket
, int ret
)
892 if (socket
->secure
&& ret
== GNUTLS_E_REHANDSHAKE
)
894 /* There is a race condition here. If application
895 * data is sent after the rehandshake request,
896 * the server thinks we ignored his request.
897 * This is a bad design of this client.
899 printf ("*** Received rehandshake request\n");
900 /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
902 ret
= do_handshake (socket
);
906 printf ("*** Rehandshake was performed.\n");
910 printf ("*** Rehandshake Failed.\n");
917 do_handshake (socket_st
* socket
)
920 gnutls_transport_set_ptr (socket
->session
,
921 (gnutls_transport_ptr_t
) socket
->fd
);
924 ret
= gnutls_handshake (socket
->session
);
928 handle_error (socket
, ret
);
931 while (ret
< 0 && gnutls_error_is_fatal (ret
) == 0);
935 /* print some information */
936 print_info (socket
->session
, socket
->hostname
, info
.insecure
);
938 if ((x509_cafile
|| pgp_keyring
) && !insecure
)
943 /* abort if verification fail */
944 rc
= gnutls_certificate_verify_peers2 (socket
->session
, &status
);
945 if (rc
!= 0 || status
!= 0)
947 printf ("*** Verifying server certificate failed...\n");
959 srp_username_callback (gnutls_session_t session
,
960 char **username
, char **password
)
962 if (srp_username
== NULL
|| srp_passwd
== NULL
)
967 *username
= gnutls_strdup (srp_username
);
968 *password
= gnutls_strdup (srp_passwd
);
973 static int psk_callback (gnutls_session_t session
,
975 gnutls_datum_t
* key
)
977 const char *hint
= gnutls_psk_client_get_hint (session
);
981 printf ("- PSK client callback. ");
983 printf ("PSK hint '%s'\n", hint
);
985 printf ("No PSK hint\n");
987 if (info
.psk_username
)
988 *username
= gnutls_strdup (info
.psk_username
);
994 printf ("Enter PSK identity: ");
996 len
= getline (&tmp
, &n
, stdin
);
1000 fprintf (stderr
, "No username given, aborting...\n");
1001 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1004 if (tmp
[strlen (tmp
) - 1] == '\n')
1005 tmp
[strlen (tmp
) - 1] = '\0';
1006 if (tmp
[strlen (tmp
) - 1] == '\r')
1007 tmp
[strlen (tmp
) - 1] = '\0';
1009 *username
= gnutls_strdup (tmp
);
1013 return GNUTLS_E_MEMORY_ERROR
;
1015 passwd
= getpass ("Enter password: ");
1018 fprintf (stderr
, "No password given, aborting...\n");
1019 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1022 ret
= gnutls_psk_netconf_derive_key (passwd
,
1028 fprintf (stderr
, "Error deriving password: %s\n", gnutls_strerror (ret
));
1029 gnutls_free (*username
);
1036 size_t res_size
= sizeof (hexkey
);
1037 gnutls_hex_encode (key
, hexkey
, &res_size
);
1038 fprintf (stderr
, "PSK username: %s\n", *username
);
1039 fprintf (stderr
, "PSK hint: %s\n", hint
);
1040 fprintf (stderr
, "PSK key: %s\n", hexkey
);
1047 init_global_tls_stuff (void)
1052 if (gnutls_certificate_allocate_credentials (&xcred
) < 0)
1054 fprintf (stderr
, "Certificate allocation memory error\n");
1058 /* there are some CAs that have a v1 certificate *%&@#*%&
1060 gnutls_certificate_set_verify_flags (xcred
,
1061 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT
);
1063 if (x509_cafile
!= NULL
)
1066 gnutls_certificate_set_x509_trust_file (xcred
,
1067 x509_cafile
, x509ctype
);
1070 fprintf (stderr
, "Error setting the x509 trust file\n");
1074 printf ("Processed %d CA certificate(s).\n", ret
);
1078 if (x509_crlfile
!= NULL
)
1081 gnutls_certificate_set_x509_crl_file (xcred
, x509_crlfile
, x509ctype
);
1084 fprintf (stderr
, "Error setting the x509 CRL file\n");
1088 printf ("Processed %d CRL(s).\n", ret
);
1095 #ifdef ENABLE_OPENPGP
1096 if (pgp_keyring
!= NULL
)
1098 ret
= gnutls_certificate_set_openpgp_keyring_file (xcred
, pgp_keyring
, GNUTLS_OPENPGP_FMT_BASE64
);
1101 fprintf (stderr
, "Error setting the OpenPGP keyring file\n");
1107 if (srp_username
&& srp_passwd
)
1110 if (gnutls_srp_allocate_client_credentials (&srp_cred
) < 0)
1112 fprintf (stderr
, "SRP authentication error\n");
1115 gnutls_srp_set_client_credentials_function (srp_cred
,
1116 srp_username_callback
);
1122 if (gnutls_psk_allocate_client_credentials (&psk_cred
) < 0)
1124 fprintf (stderr
, "PSK authentication error\n");
1127 if (psk_username
&& psk_key
.data
)
1129 ret
= gnutls_psk_set_client_credentials (psk_cred
,
1130 psk_username
, &psk_key
,
1131 GNUTLS_PSK_KEY_HEX
);
1134 fprintf (stderr
, "Error setting the PSK credentials: %s\n",
1135 gnutls_strerror (ret
));
1138 gnutls_psk_set_client_credentials_function (psk_cred
, psk_callback
);
1143 if (gnutls_anon_allocate_client_credentials (&anon_cred
) < 0)
1145 fprintf (stderr
, "Anonymous authentication error\n");
1151 /* Functions to manipulate sockets
1155 socket_recv (const socket_st
* socket
, void *buffer
, int buffer_size
)
1162 ret
= gnutls_record_recv (socket
->session
, buffer
, buffer_size
);
1164 while (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
);
1168 ret
= recv (socket
->fd
, buffer
, buffer_size
, 0);
1170 while (ret
== -1 && errno
== EINTR
);
1176 socket_send (const socket_st
* socket
, const void *buffer
, int buffer_size
)
1183 ret
= gnutls_record_send (socket
->session
, buffer
, buffer_size
);
1185 while (ret
== GNUTLS_E_AGAIN
|| ret
== GNUTLS_E_INTERRUPTED
);
1189 ret
= send (socket
->fd
, buffer
, buffer_size
, 0);
1191 while (ret
== -1 && errno
== EINTR
);
1193 if (ret
> 0 && ret
!= buffer_size
&& verbose
)
1195 "*** Only sent %d bytes instead of %d.\n", ret
, buffer_size
);
1201 socket_bye (socket_st
* socket
)
1207 ret
= gnutls_bye (socket
->session
, GNUTLS_SHUT_RDWR
);
1208 while (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
);
1210 fprintf (stderr
, "*** gnutls_bye() error: %s\n",
1211 gnutls_strerror (ret
));
1212 gnutls_deinit (socket
->session
);
1213 socket
->session
= NULL
;
1216 freeaddrinfo (socket
->addr_info
);
1217 socket
->addr_info
= socket
->ptr
= NULL
;
1220 free (socket
->hostname
);
1221 free (socket
->service
);
1223 shutdown (socket
->fd
, SHUT_RDWR
); /* no more receptions */
1231 socket_connect (const socket_st
* hd
)
1235 printf ("Connecting to '%s:%s'...\n", hd
->ip
, hd
->service
);
1237 err
= connect (hd
->fd
, hd
->ptr
->ai_addr
, hd
->ptr
->ai_addrlen
);
1240 fprintf (stderr
, "Cannot connect to %s:%s: %s\n", hd
->hostname
,
1241 hd
->service
, strerror (errno
));
1247 socket_open (socket_st
* hd
, const char *hostname
, const char *service
)
1249 struct addrinfo hints
, *res
, *ptr
;
1251 char buffer
[MAX_BUF
+ 1];
1252 char portname
[16] = { 0 };
1254 printf ("Resolving '%s'...\n", hostname
);
1255 /* get server name */
1256 memset (&hints
, 0, sizeof (hints
));
1257 hints
.ai_socktype
= SOCK_STREAM
;
1258 if ((err
= getaddrinfo (hostname
, service
, &hints
, &res
)))
1260 fprintf (stderr
, "Cannot resolve %s:%s: %s\n", hostname
, service
,
1261 gai_strerror (err
));
1266 for (ptr
= res
; ptr
!= NULL
; ptr
= ptr
->ai_next
)
1268 sd
= socket (ptr
->ai_family
, ptr
->ai_socktype
, ptr
->ai_protocol
);
1272 if ((err
= getnameinfo (ptr
->ai_addr
, ptr
->ai_addrlen
, buffer
, MAX_BUF
,
1273 portname
, sizeof (portname
),
1274 NI_NUMERICHOST
| NI_NUMERICSERV
)) != 0)
1276 fprintf (stderr
, "getnameinfo(): %s\n", gai_strerror (err
));
1286 fprintf (stderr
, "socket(): %s\n", strerror (errno
));
1292 hd
->hostname
= strdup (hostname
);
1293 hd
->ip
= strdup (buffer
);
1294 hd
->service
= strdup (portname
);
1296 hd
->addr_info
= res
;