int main (int argc, char **argv) { int err, ret; int ii, i; char buffer[MAX_BUF + 1]; char *session_data = NULL; char *session_id = NULL; size_t session_data_size; size_t session_id_size; fd_set rset; int maxfd; struct timeval tv; int user_term = 0, retval = 0; socket_st hd; ssize_t bytes; set_program_name (argv[0]); gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); #ifdef gcry_fips_mode_active /* Libgcrypt manual says that gcry_version_check must be called before calling gcry_fips_mode_active. */ gcry_check_version (NULL); if (gcry_fips_mode_active ()) { ret = gnutls_register_md5_handler (); if (ret) fprintf (stderr, "gnutls_register_md5_handler: %s\n", gnutls_strerror (ret)); } #endif if ((ret = gnutls_global_init ()) < 0) { fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret)); exit (1); } if ((ret = gnutls_global_init_extra ()) < 0) { fprintf (stderr, "global_init_extra: %s\n", gnutls_strerror (ret)); exit (1); } gaa_parser (argc, argv); if (hostname == NULL) { fprintf (stderr, "No hostname given\n"); exit (1); } gnutls_global_set_log_function (tls_log_func); gnutls_global_set_log_level (info.debug); sockets_init (); #ifndef _WIN32 signal (SIGPIPE, SIG_IGN); #endif init_global_tls_stuff (); socket_open (&hd, hostname, service); socket_connect (&hd); hd.session = init_tls_session (hostname); if (starttls) goto after_handshake; for (i = 0; i < 2; i++) { if (i == 1) { hd.session = init_tls_session (hostname); gnutls_session_set_data (hd.session, session_data, session_data_size); free (session_data); } ret = do_handshake (&hd); if (ret < 0) { fprintf (stderr, "*** Handshake has failed\n"); gnutls_perror (ret); gnutls_deinit (hd.session); return 1; } else { printf ("- Handshake was completed\n"); if (gnutls_session_is_resumed (hd.session) != 0) printf ("*** This is a resumed session\n"); } if (resume != 0 && i == 0) { gnutls_session_get_data (hd.session, NULL, &session_data_size); session_data = malloc (session_data_size); gnutls_session_get_data (hd.session, session_data, &session_data_size); gnutls_session_get_id (hd.session, NULL, &session_id_size); session_id = malloc (session_id_size); gnutls_session_get_id (hd.session, session_id, &session_id_size); /* print some information */ print_info (hd.session, hostname, info.insecure); printf ("- Disconnecting\n"); socket_bye (&hd); printf ("\n\n- Connecting again- trying to resume previous session\n"); socket_open (&hd, hostname, service); socket_connect (&hd); } else { break; } } after_handshake: /* Warning! Do not touch this text string, it is used by external programs to search for when gnutls-cli has reached this point. */ printf ("\n- Simple Client Mode:\n\n"); if (rehandshake) { ret = do_handshake (&hd); if (ret < 0) { fprintf (stderr, "*** ReHandshake has failed\n"); gnutls_perror (ret); gnutls_deinit (hd.session); return 1; } else { printf ("- ReHandshake was completed\n"); } } #ifndef _WIN32 signal (SIGALRM, &starttls_alarm); #endif fflush(stdout); fflush(stderr); /* do not buffer */ #if !(defined _WIN32 || defined __WIN32__) setbuf (stdin, NULL); #endif setbuf (stdout, NULL); setbuf (stderr, NULL); for (;;) { if (starttls_alarmed && !hd.secure) { /* Warning! Do not touch this text string, it is used by external programs to search for when gnutls-cli has reached this point. */ fprintf (stderr, "*** Starting TLS handshake\n"); ret = do_handshake (&hd); if (ret < 0) { fprintf (stderr, "*** Handshake has failed\n"); user_term = 1; retval = 1; break; } } FD_ZERO (&rset); FD_SET (fileno (stdin), &rset); FD_SET (hd.fd, &rset); maxfd = MAX (fileno (stdin), hd.fd); tv.tv_sec = 3; tv.tv_usec = 0; err = select (maxfd + 1, &rset, NULL, NULL, &tv); if (err < 0) continue; if (FD_ISSET (hd.fd, &rset)) { memset (buffer, 0, MAX_BUF + 1); ret = socket_recv (&hd, buffer, MAX_BUF); if (ret == 0) { printf ("- Peer has closed the GnuTLS connection\n"); break; } else if (handle_error (&hd, ret) < 0 && user_term == 0) { fprintf (stderr, "*** Server has terminated the connection abnormally.\n"); retval = 1; break; } else if (ret > 0) { if (verbose != 0) printf ("- Received[%d]: ", ret); for (ii = 0; ii < ret; ii++) { fputc (buffer[ii], stdout); } fflush (stdout); } if (user_term != 0) break; } if (FD_ISSET (fileno (stdin), &rset)) { if ((bytes = read (fileno (stdin), buffer, MAX_BUF - 1)) <= 0) { if (hd.secure == 0) { /* Warning! Do not touch this text string, it is used by external programs to search for when gnutls-cli has reached this point. */ fprintf (stderr, "*** Starting TLS handshake\n"); ret = do_handshake (&hd); clearerr (stdin); if (ret < 0) { fprintf (stderr, "*** Handshake has failed\n"); user_term = 1; retval = 1; break; } } else { user_term = 1; break; } continue; } if (crlf != 0) { char *b = strchr (buffer, '\n'); if (b != NULL) { strcpy (b, "\r\n"); bytes++; } } ret = socket_send (&hd, buffer, bytes); if (ret > 0) { if (verbose != 0) printf ("- Sent: %d bytes\n", ret); } else handle_error (&hd, ret); } } if (info.debug) gcry_control (GCRYCTL_DUMP_RANDOM_STATS); if (user_term != 0) socket_bye (&hd); else gnutls_deinit (hd.session); #ifdef ENABLE_SRP if (srp_cred) gnutls_srp_free_client_credentials (srp_cred); #endif #ifdef ENABLE_PSK if (psk_cred) gnutls_psk_free_client_credentials (psk_cred); #endif gnutls_certificate_free_credentials (xcred); #ifdef ENABLE_ANON gnutls_anon_free_client_credentials (anon_cred); #endif gnutls_global_deinit (); return retval; }
void socket_open(socket_st * hd, const char *hostname, const char *service, const char *app_proto, int flags, const char *msg, gnutls_datum_t *rdata) { struct addrinfo hints, *res, *ptr; int sd, err = 0; int udp = flags & SOCKET_FLAG_UDP; int ret; int fastopen = flags & SOCKET_FLAG_FASTOPEN; char buffer[MAX_BUF + 1]; char portname[16] = { 0 }; gnutls_datum_t idna; char *a_hostname; memset(hd, 0, sizeof(*hd)); if (flags & SOCKET_FLAG_VERBOSE) hd->verbose = 1; if (rdata) { hd->rdata.data = rdata->data; hd->rdata.size = rdata->size; } ret = gnutls_idna_map(hostname, strlen(hostname), &idna, 0); if (ret < 0) { fprintf(stderr, "Cannot convert %s to IDNA: %s\n", hostname, gnutls_strerror(ret)); exit(1); } hd->hostname = strdup(hostname); a_hostname = (char*)idna.data; if (msg != NULL) printf("Resolving '%s:%s'...\n", a_hostname, service); /* get server name */ memset(&hints, 0, sizeof(hints)); hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; if ((err = getaddrinfo(a_hostname, service, &hints, &res))) { fprintf(stderr, "Cannot resolve %s:%s: %s\n", hostname, service, gai_strerror(err)); exit(1); } sd = -1; for (ptr = res; ptr != NULL; ptr = ptr->ai_next) { sd = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); if (sd == -1) continue; if ((err = getnameinfo(ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF, portname, sizeof(portname), NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { fprintf(stderr, "getnameinfo(): %s\n", gai_strerror(err)); continue; } if (hints.ai_socktype == SOCK_DGRAM) { #if defined(IP_DONTFRAG) int yes = 1; if (setsockopt(sd, IPPROTO_IP, IP_DONTFRAG, (const void *) &yes, sizeof(yes)) < 0) perror("setsockopt(IP_DF) failed"); #elif defined(IP_MTU_DISCOVER) int yes = IP_PMTUDISC_DO; if (setsockopt(sd, IPPROTO_IP, IP_MTU_DISCOVER, (const void *) &yes, sizeof(yes)) < 0) perror("setsockopt(IP_DF) failed"); #endif } if (fastopen && ptr->ai_socktype == SOCK_STREAM && (ptr->ai_family == AF_INET || ptr->ai_family == AF_INET6)) { memcpy(&hd->connect_addr, ptr->ai_addr, ptr->ai_addrlen); hd->connect_addrlen = ptr->ai_addrlen; if (msg) printf("%s '%s:%s' (TFO)...\n", msg, buffer, portname); } else { if (msg) printf("%s '%s:%s'...\n", msg, buffer, portname); if ((err = connect(sd, ptr->ai_addr, ptr->ai_addrlen)) < 0) continue; } hd->fd = sd; if (flags & SOCKET_FLAG_STARTTLS) { hd->app_proto = app_proto; socket_starttls(hd); hd->app_proto = NULL; } if (!(flags & SOCKET_FLAG_SKIP_INIT)) { hd->session = init_tls_session(hostname); if (hd->session == NULL) { fprintf(stderr, "error initializing session\n"); exit(1); } } if (hd->session) { if (hd->rdata.data) { gnutls_session_set_data(hd->session, hd->rdata.data, hd->rdata.size); } gnutls_transport_set_int(hd->session, sd); } if (!(flags & SOCKET_FLAG_RAW) && !(flags & SOCKET_FLAG_SKIP_INIT)) { err = do_handshake(hd); if (err == GNUTLS_E_PUSH_ERROR) { /* failed connecting */ gnutls_deinit(hd->session); hd->session = NULL; continue; } else if (err < 0) { fprintf(stderr, "*** handshake has failed: %s\n", gnutls_strerror(err)); exit(1); } } break; } if (err != 0) { int e = errno; fprintf(stderr, "Could not connect to %s:%s: %s\n", buffer, portname, strerror(e)); exit(1); } if (sd == -1) { fprintf(stderr, "Could not find a supported socket\n"); exit(1); } if ((flags & SOCKET_FLAG_RAW) || (flags & SOCKET_FLAG_SKIP_INIT)) hd->secure = 0; else hd->secure = 1; hd->fd = sd; hd->ip = strdup(buffer); hd->service = strdup(portname); hd->ptr = ptr; hd->addr_info = res; hd->rdata.data = NULL; gnutls_free(idna.data); return; }
int main (int argc, char **argv) { int ret; int ii, i, inp; char buffer[MAX_BUF + 1]; char *session_data = NULL; char *session_id = NULL; size_t session_data_size; size_t session_id_size = 0; int user_term = 0, retval = 0; socket_st hd; ssize_t bytes; set_program_name (argv[0]); gaa_parser (argc, argv); gnutls_global_set_log_function (tls_log_func); gnutls_global_set_log_level (info.debug); if ((ret = gnutls_global_init ()) < 0) { fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret)); exit (1); } #ifdef ENABLE_PKCS11 pkcs11_common (); #endif if (hostname == NULL) { fprintf (stderr, "No hostname given\n"); exit (1); } sockets_init (); #ifndef _WIN32 signal (SIGPIPE, SIG_IGN); #endif init_global_tls_stuff (); socket_open (&hd, hostname, service); socket_connect (&hd); hd.session = init_tls_session (hostname); if (starttls) goto after_handshake; for (i = 0; i < 2; i++) { if (i == 1) { hd.session = init_tls_session (hostname); gnutls_session_set_data (hd.session, session_data, session_data_size); free (session_data); } ret = do_handshake (&hd); if (ret < 0) { fprintf (stderr, "*** Handshake has failed\n"); gnutls_perror (ret); gnutls_deinit (hd.session); return 1; } else { printf ("- Handshake was completed\n"); if (gnutls_session_is_resumed (hd.session) != 0) printf ("*** This is a resumed session\n"); } if (resume != 0 && i == 0) { gnutls_session_get_data (hd.session, NULL, &session_data_size); session_data = malloc (session_data_size); gnutls_session_get_data (hd.session, session_data, &session_data_size); gnutls_session_get_id (hd.session, NULL, &session_id_size); session_id = malloc (session_id_size); gnutls_session_get_id (hd.session, session_id, &session_id_size); /* print some information */ print_info (hd.session, hostname, info.insecure); printf ("- Disconnecting\n"); socket_bye (&hd); printf ("\n\n- Connecting again- trying to resume previous session\n"); socket_open (&hd, hostname, service); socket_connect (&hd); } else { break; } } after_handshake: /* Warning! Do not touch this text string, it is used by external programs to search for when gnutls-cli has reached this point. */ printf ("\n- Simple Client Mode:\n\n"); if (rehandshake) { ret = do_handshake (&hd); if (ret < 0) { fprintf (stderr, "*** ReHandshake has failed\n"); gnutls_perror (ret); gnutls_deinit (hd.session); return 1; } else { printf ("- ReHandshake was completed\n"); } } #ifndef _WIN32 signal (SIGALRM, &starttls_alarm); #endif fflush (stdout); fflush (stderr); /* do not buffer */ #if !(defined _WIN32 || defined __WIN32__) setbuf (stdin, NULL); #endif setbuf (stdout, NULL); setbuf (stderr, NULL); for (;;) { if (starttls_alarmed && !hd.secure) { /* Warning! Do not touch this text string, it is used by external programs to search for when gnutls-cli has reached this point. */ fprintf (stderr, "*** Starting TLS handshake\n"); ret = do_handshake (&hd); if (ret < 0) { fprintf (stderr, "*** Handshake has failed\n"); user_term = 1; retval = 1; break; } } inp = check_net_or_keyboard_input(&hd); if (inp == IN_NET) { memset (buffer, 0, MAX_BUF + 1); ret = socket_recv (&hd, buffer, MAX_BUF); if (ret == 0) { printf ("- Peer has closed the GnuTLS connection\n"); break; } else if (handle_error (&hd, ret) < 0 && user_term == 0) { fprintf (stderr, "*** Server has terminated the connection abnormally.\n"); retval = 1; break; } else if (ret > 0) { if (verbose != 0) printf ("- Received[%d]: ", ret); for (ii = 0; ii < ret; ii++) { fputc (buffer[ii], stdout); } fflush (stdout); } if (user_term != 0) break; } if (inp == IN_KEYBOARD) { if ((bytes = read (fileno (stdin), buffer, MAX_BUF - 1)) <= 0) { if (hd.secure == 0) { /* Warning! Do not touch this text string, it is used by external programs to search for when gnutls-cli has reached this point. */ fprintf (stderr, "*** Starting TLS handshake\n"); ret = do_handshake (&hd); clearerr (stdin); if (ret < 0) { fprintf (stderr, "*** Handshake has failed\n"); user_term = 1; retval = 1; break; } } else { user_term = 1; break; } continue; } buffer[bytes] = 0; if (crlf != 0) { char *b = strchr (buffer, '\n'); if (b != NULL) { strcpy (b, "\r\n"); bytes++; } } ret = socket_send (&hd, buffer, bytes); if (ret > 0) { if (verbose != 0) printf ("- Sent: %d bytes\n", ret); } else handle_error (&hd, ret); } } if (user_term != 0) socket_bye (&hd); else gnutls_deinit (hd.session); #ifdef ENABLE_SRP if (srp_cred) gnutls_srp_free_client_credentials (srp_cred); #endif #ifdef ENABLE_PSK if (psk_cred) gnutls_psk_free_client_credentials (psk_cred); #endif gnutls_certificate_free_credentials (xcred); #ifdef ENABLE_ANON gnutls_anon_free_client_credentials (anon_cred); #endif gnutls_global_deinit (); return retval; }
int main (int argc, char **argv) { int err, ret; int ii, i; char buffer[MAX_BUF + 1]; char *session_data = NULL; char *session_id = NULL; size_t session_data_size; size_t session_id_size; fd_set rset; int maxfd; struct timeval tv; int user_term = 0; socket_st hd; gaa_parser (argc, argv); if (hostname == NULL) { fprintf (stderr, "No hostname given\n"); exit (1); } sockets_init (); #ifndef _WIN32 signal (SIGPIPE, SIG_IGN); #endif init_global_tls_stuff (); socket_open( &hd, hostname, service); socket_connect( &hd); hd.session = init_tls_session (hostname); if (starttls) goto after_handshake; for (i = 0; i < 2; i++) { if (i == 1) { hd.session = init_tls_session (hostname); gnutls_session_set_data (hd.session, session_data, session_data_size); free (session_data); } ret = do_handshake (&hd); if (ret < 0) { fprintf (stderr, "*** Handshake has failed\n"); gnutls_perror (ret); gnutls_deinit (hd.session); return 1; } else { printf ("- Handshake was completed\n"); if (gnutls_session_is_resumed (hd.session) != 0) printf ("*** This is a resumed session\n"); } if (resume != 0 && i == 0) { gnutls_session_get_data (hd.session, NULL, &session_data_size); session_data = malloc (session_data_size); gnutls_session_get_data (hd.session, session_data, &session_data_size); gnutls_session_get_id (hd.session, NULL, &session_id_size); session_id = malloc (session_id_size); gnutls_session_get_id (hd.session, session_id, &session_id_size); /* print some information */ print_info (hd.session, hostname); printf ("- Disconnecting\n"); socket_bye (&hd); printf ("\n\n- Connecting again- trying to resume previous session\n"); socket_open( &hd, hostname, service); socket_connect(&hd); } else { break; } } after_handshake: printf ("\n- Simple Client Mode:\n\n"); #ifndef _WIN32 signal (SIGALRM, &starttls_alarm); #endif /* do not buffer */ #if !(defined _WIN32 || defined __WIN32__) setbuf (stdin, NULL); #endif setbuf (stdout, NULL); setbuf (stderr, NULL); for (;;) { if (starttls_alarmed && !hd.secure) { fprintf (stderr, "*** Starting TLS handshake\n"); ret = do_handshake (&hd); if (ret < 0) { fprintf (stderr, "*** Handshake has failed\n"); socket_bye (&hd); user_term = 1; break; } } FD_ZERO (&rset); FD_SET (fileno (stdin), &rset); FD_SET (hd.fd, &rset); maxfd = MAX (fileno (stdin), hd.fd); tv.tv_sec = 3; tv.tv_usec = 0; err = select (maxfd + 1, &rset, NULL, NULL, &tv); if (err < 0) continue; if (FD_ISSET (hd.fd, &rset)) { memset (buffer, 0, MAX_BUF + 1); ret = socket_recv (&hd, buffer, MAX_BUF); if (ret == 0) { printf ("- Peer has closed the GNUTLS connection\n"); break; } else if (handle_error (&hd, ret) < 0 && user_term == 0) { fprintf (stderr, "*** Server has terminated the connection abnormally.\n"); break; } else if (ret > 0) { if (verbose != 0) printf ("- Received[%d]: ", ret); for (ii = 0; ii < ret; ii++) { fputc (buffer[ii], stdout); } fflush (stdout); } if (user_term != 0) break; } if (FD_ISSET (fileno (stdin), &rset)) { if (fgets (buffer, MAX_BUF, stdin) == NULL) { if (hd.secure == 0) { fprintf (stderr, "*** Starting TLS handshake\n"); ret = do_handshake (&hd); if (ret < 0) { fprintf (stderr, "*** Handshake has failed\n"); socket_bye (&hd); user_term = 1; } } else { user_term = 1; break; } continue; } if (crlf != 0) { char *b = strchr (buffer, '\n'); if (b != NULL) strcpy (b, "\r\n"); } ret = socket_send (&hd, buffer, strlen (buffer)); if (ret > 0) { if (verbose != 0) printf ("- Sent: %d bytes\n", ret); } else handle_error (&hd, ret); } } if (user_term != 0) socket_bye (&hd); else gnutls_deinit (hd.session); #ifdef ENABLE_SRP gnutls_srp_free_client_credentials (srp_cred); #endif #ifdef ENABLE_PSK gnutls_psk_free_client_credentials (psk_cred); #endif gnutls_certificate_free_credentials (xcred); #ifdef ENABLE_ANON gnutls_anon_free_client_credentials (anon_cred); #endif gnutls_global_deinit (); return 0; }