diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | src/cli-args.def | 7 | ||||
-rw-r--r-- | src/cli.c | 106 | ||||
-rw-r--r-- | src/common.c | 275 | ||||
-rw-r--r-- | src/common.h | 3 | ||||
-rw-r--r-- | src/socket.c | 27 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rwxr-xr-x | tests/logfile-option.sh | 113 |
8 files changed, 348 insertions, 187 deletions
@@ -30,6 +30,8 @@ See the end for copying conditions. negotiation and was sent even on TLS 1.3. It is now sent only when TLS 1.2 or earlier is negotiated (#689). +** gnutls-cli: Added option --logfile to redirect informational messages output. + ** API and ABI modifications: No changes since last version. diff --git a/src/cli-args.def b/src/cli-args.def index 1e06e12d3a..518a97466e 100644 --- a/src/cli-args.def +++ b/src/cli-args.def @@ -416,6 +416,13 @@ flag = { doc = ""; }; +flag = { + name = logfile; + arg-type = string; + descrip = "Redirect informational messages to a specific file."; + doc = ""; +}; + doc-section = { ds-type = 'SEE ALSO'; // or anything else ds-format = 'texi'; // or texi or mdoc format @@ -363,21 +363,21 @@ static int cert_verify_callback(gnutls_session_t session) if (ca_verify) { rc = cert_verify(session, host, GNUTLS_KP_TLS_WWW_SERVER); if (rc == 0) { - printf - ("*** PKI verification of server certificate failed...\n"); + log_msg + (stdout, "*** PKI verification of server certificate failed...\n"); if (!insecure && !ssh) return -1; } else if (ENABLED_OPT(OCSP) && gnutls_ocsp_status_request_is_checked(session, 0) == 0) { /* off-line verification succeeded. Try OCSP */ rc = cert_verify_ocsp(session); if (rc == -1) { - printf - ("*** Verifying (with OCSP) server certificate chain failed...\n"); + log_msg + (stdout, "*** Verifying (with OCSP) server certificate chain failed...\n"); if (!insecure && !ssh) return -1; } else if (rc == 0) - printf("*** OCSP: nothing to check.\n"); + log_msg(stdout, "*** OCSP: nothing to check.\n"); else - printf("*** OCSP: verified %d certificate(s).\n", rc); + log_msg(stdout, "*** OCSP: verified %d certificate(s).\n", rc); } } @@ -518,10 +518,10 @@ cert_callback(gnutls_session_t session, /* Print the server's trusted CAs */ if (nreqs > 0) - printf("- Server's trusted authorities:\n"); + log_msg(stdout, "- Server's trusted authorities:\n"); else - printf - ("- Server did not send us any trusted authorities names.\n"); + log_msg + (stdout, "- Server did not send us any trusted authorities names.\n"); /* print the names (if any) */ for (i = 0; i < nreqs; i++) { @@ -530,8 +530,8 @@ cert_callback(gnutls_session_t session, gnutls_x509_rdn_get(&req_ca_rdn[i], issuer_dn, &len); if (ret >= 0) { - printf(" [%d]: ", i); - printf("%s\n", issuer_dn); + log_msg(stdout, " [%d]: ", i); + log_msg(stdout, "%s\n", issuer_dn); } } } @@ -550,8 +550,8 @@ cert_callback(gnutls_session_t session, if (x509_key != NULL) { *pkey = x509_key; } else { - printf - ("- Could not find a suitable key to send to server\n"); + log_msg + (stdout, "- Could not find a suitable key to send to server\n"); return -1; } @@ -560,7 +560,7 @@ cert_callback(gnutls_session_t session, } } - printf("- Successfully sent %u certificate(s) to server.\n", + log_msg(stdout, "- Successfully sent %u certificate(s) to server.\n", *pcert_length); return 0; @@ -717,7 +717,7 @@ static int handle_error(socket_st * hd, int err) str = gnutls_alert_get_name(alert); if (str == NULL) str = str_unknown; - printf("*** Received alert [%d]: %s\n", alert, str); + log_msg(stdout, "*** Received alert [%d]: %s\n", alert, str); } check_server_cmd(hd, err); @@ -813,7 +813,7 @@ static int try_rehandshake(socket_st * hd) gnutls_perror(ret); return ret; } else { - printf("- ReHandshake was completed\n"); + log_msg(stdout, "- ReHandshake was completed\n"); return 0; } } @@ -830,7 +830,7 @@ static int try_rekey(socket_st * hd, unsigned peer) fprintf(stderr, "*** Rekey has failed: %s\n", gnutls_strerror(ret)); return ret; } else { - printf("- Rekey was completed\n"); + log_msg(stdout, "- Rekey was completed\n"); return 0; } } @@ -854,13 +854,13 @@ static int try_resume(socket_st * hd) hd->rdata.data = NULL; } - printf("- Disconnecting\n"); + log_msg(stdout, "- Disconnecting\n"); socket_bye(hd, 1); canonicalize_host(hostname, service, sizeof(service)); - printf - ("\n\n- Connecting again- trying to resume previous session\n"); + log_msg + (stdout, "\n\n- Connecting again- trying to resume previous session\n"); if (HAVE_OPT(STARTTLS_PROTO)) socket_flags |= SOCKET_FLAG_STARTTLS; else if (fastopen) @@ -886,9 +886,9 @@ static int try_resume(socket_st * hd) socket_open3(hd, hostname, service, OPT_ARG(STARTTLS_PROTO), socket_flags, CONNECT_MSG, &rdata, &edata); - printf("- Resume Handshake was completed\n"); + log_msg(stdout, "- Resume Handshake was completed\n"); if (gnutls_session_is_resumed(hd->session) != 0) - printf("*** This is a resumed session\n"); + log_msg(stdout, "*** This is a resumed session\n"); return 0; } @@ -1128,12 +1128,22 @@ int main(int argc, char **argv) int socket_flags = SOCKET_FLAG_DONT_PRINT_ERRORS; FILE *server_fp = NULL; FILE *client_fp = NULL; + FILE *logfile = NULL; #ifndef _WIN32 struct sigaction new_action; #endif cmd_parser(argc, argv); + if (HAVE_OPT(LOGFILE)) { + logfile = fopen(OPT_ARG(LOGFILE), "w+"); + if (!logfile) { + log_msg(stderr, "Unable to open '%s'!\n", OPT_ARG(LOGFILE)); + exit(1); + } + log_set(logfile); + } + gnutls_global_set_log_function(tls_log_func); gnutls_global_set_log_level(OPT_VALUE_DEBUG); @@ -1178,7 +1188,7 @@ int main(int argc, char **argv) hd.verbose = verbose; if (hd.secure) { - printf("- Handshake was completed\n"); + log_msg(stdout, "- Handshake was completed\n"); if (resume != 0) if (try_resume(&hd)) { @@ -1191,7 +1201,7 @@ int main(int argc, char **argv) /* 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"); + log_msg(stdout, "\n- Simple Client Mode:\n\n"); if (rehandshake) if (try_rehandshake(&hd)) { @@ -1246,8 +1256,8 @@ int main(int argc, char **argv) ret = socket_recv(&hd, buffer, MAX_BUF); if (ret == 0 || (ret == GNUTLS_E_PREMATURE_TERMINATION && user_term)) { - printf - ("- Peer has closed the GnuTLS connection\n"); + log_msg + (stdout, "- Peer has closed the GnuTLS connection\n"); break; } else if (handle_error(&hd, ret) < 0) { fprintf(stderr, @@ -1256,7 +1266,7 @@ int main(int argc, char **argv) break; } else if (ret > 0) { if (verbose != 0) - printf("- Received[%d]: ", ret); + log_msg(stdout, "- Received[%d]: ", ret); for (ii = 0; ii < ret; ii++) { fputc(buffer[ii], stdout); } @@ -1346,7 +1356,7 @@ int main(int argc, char **argv) if (ret > 0) { if (verbose != 0) - printf("- Sent: %d bytes\n", ret); + log_msg(stdout, "- Sent: %d bytes\n", ret); } else handle_error(&hd, ret); @@ -1364,6 +1374,10 @@ int main(int argc, char **argv) cleanup: socket_bye(&hd, 0); + if (logfile) { + fclose(logfile); + logfile = NULL; + } #ifdef ENABLE_SRP if (srp_cred) @@ -1392,21 +1406,21 @@ void print_priority_list(void) const char *str; unsigned int lineb = 0; - printf("Priority strings in GnuTLS %s:\n", gnutls_check_version(NULL)); + log_msg(stdout, "Priority strings in GnuTLS %s:\n", gnutls_check_version(NULL)); fputs("\t", stdout); for (idx=0;;idx++) { str = gnutls_priority_string_list(idx, GNUTLS_PRIORITY_LIST_INIT_KEYWORDS); if (str == NULL) break; - lineb += printf("%s ", str); + lineb += log_msg(stdout, "%s ", str); if (lineb > 64) { lineb = 0; - printf("\n\t"); + log_msg(stdout, "\n\t"); } } - printf("\n\nSpecial strings:\n"); + log_msg(stdout, "\n\nSpecial strings:\n"); lineb = 0; fputs("\t", stdout); for (idx=0;;idx++) { @@ -1415,13 +1429,13 @@ void print_priority_list(void) break; if (str[0] == 0) continue; - lineb += printf("%%%s ", str); + lineb += log_msg(stdout, "%%%s ", str); if (lineb > 64) { lineb = 0; - printf("\n\t"); + log_msg(stdout, "\n\t"); } } - printf("\n"); + log_msg(stdout, "\n"); return; } @@ -1593,15 +1607,15 @@ static void check_server_cmd(socket_st * socket, int ret) * the server thinks we ignored his request. * This is a bad design of this client. */ - printf("*** Received rehandshake request\n"); + log_msg(stdout, "*** Received rehandshake request\n"); /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */ ret = do_handshake(socket); if (ret == 0) { - printf("*** Rehandshake was performed.\n"); + log_msg(stdout, "*** Rehandshake was performed.\n"); } else { - printf("*** Rehandshake Failed: %s\n", gnutls_strerror(ret)); + log_msg(stdout, "*** Rehandshake Failed: %s\n", gnutls_strerror(ret)); } } else if (ret == GNUTLS_E_REAUTH_REQUEST) { do { @@ -1609,9 +1623,9 @@ static void check_server_cmd(socket_st * socket, int ret) } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret == 0) { - printf("*** Re-auth was performed.\n"); + log_msg(stdout, "*** Re-auth was performed.\n"); } else { - printf("*** Re-auth failed: %s\n", gnutls_strerror(ret)); + log_msg(stdout, "*** Re-auth failed: %s\n", gnutls_strerror(ret)); } } } @@ -1678,11 +1692,11 @@ psk_callback(gnutls_session_t session, char **username, size_t res_size; gnutls_datum_t tmp; - printf("- PSK client callback. "); + log_msg(stdout, "- PSK client callback. "); if (hint) - printf("PSK hint '%s'\n", hint); + log_msg(stdout, "PSK hint '%s'\n", hint); else - printf("No PSK hint\n"); + log_msg(stdout, "No PSK hint\n"); if (HAVE_OPT(PSKUSERNAME)) *username = gnutls_strdup(OPT_ARG(PSKUSERNAME)); @@ -1690,7 +1704,7 @@ psk_callback(gnutls_session_t session, char **username, char *p = NULL; size_t n; - printf("Enter PSK identity: "); + log_msg(stdout, "Enter PSK identity: "); fflush(stdout); ret = getline(&p, &n, stdin); @@ -1805,7 +1819,7 @@ static void init_global_tls_stuff(void) fprintf(stderr, "Error setting the x509 trust file: %s\n", gnutls_strerror(ret)); exit(1); } else { - printf("Processed %d CA certificate(s).\n", ret); + log_msg(stdout, "Processed %d CA certificate(s).\n", ret); } if (x509_crlfile != NULL) { @@ -1818,7 +1832,7 @@ static void init_global_tls_stuff(void) "Error setting the x509 CRL file: %s\n", gnutls_strerror(ret)); exit(1); } else { - printf("Processed %d CRL(s).\n", ret); + log_msg(stdout, "Processed %d CRL(s).\n", ret); } } diff --git a/src/common.c b/src/common.c index b1cb519e2f..f0fdf9e00d 100644 --- a/src/common.c +++ b/src/common.c @@ -52,6 +52,7 @@ const char str_unknown[] = "(unknown)"; +static FILE *logfile = NULL; /* Hex encodes the given data adding a semicolon between hex bytes. */ const char *raw_to_string(const unsigned char *raw, size_t raw_size) @@ -145,7 +146,7 @@ static void print_x509_info_compact(gnutls_session_t session, int print_crt_stat ret = gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_COMPACT, &cinfo); if (ret == 0) { - printf("- X.509 cert: %s\n", cinfo.data); + log_msg(stdout, "- X.509 cert: %s\n", cinfo.data); gnutls_free(cinfo.data); } @@ -249,12 +250,12 @@ int cert_verify(gnutls_session_t session, const char *hostname, const char *purp rc = gnutls_certificate_verify_peers(session, data, elements, &status); if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) { - printf("- Peer did not send any certificate.\n"); + log_msg(stdout, "- Peer did not send any certificate.\n"); return 0; } if (rc < 0) { - printf("- Could not verify certificate (err: %s)\n", + log_msg(stdout, "- Could not verify certificate (err: %s)\n", gnutls_strerror(rc)); return 0; } @@ -263,12 +264,12 @@ int cert_verify(gnutls_session_t session, const char *hostname, const char *purp rc = gnutls_certificate_verification_status_print(status, type, &out, 0); if (rc < 0) { - printf("- Could not print verification flags (err: %s)\n", + log_msg(stdout, "- Could not print verification flags (err: %s)\n", gnutls_strerror(rc)); return 0; } - printf("- Status: %s\n", out.data); + log_msg(stdout, "- Status: %s\n", out.data); gnutls_free(out.data); @@ -298,12 +299,12 @@ print_dh_info(gnutls_session_t session, const char *str, int print) return; } - printf("- %sDiffie-Hellman parameters\n", str); - printf(" - Using prime: %d bits\n", + log_msg(stdout, "- %sDiffie-Hellman parameters\n", str); + log_msg(stdout, " - Using prime: %d bits\n", gnutls_dh_get_prime_bits(session)); - printf(" - Secret key: %d bits\n", + log_msg(stdout, " - Secret key: %d bits\n", gnutls_dh_get_secret_bits(session)); - printf(" - Peer's public key: %d bits\n", + log_msg(stdout, " - Peer's public key: %d bits\n", gnutls_dh_get_peers_public_bits(session)); ret = gnutls_dh_get_group(session, &raw_gen, &raw_prime); @@ -354,7 +355,7 @@ print_dh_info(gnutls_session_t session, const char *str, int print) goto out; } - printf(" - PKCS#3 format:\n\n%.*s\n", + log_msg(stdout, " - PKCS#3 format:\n\n%.*s\n", (int) params_data_size, params_data); out: @@ -372,12 +373,12 @@ static void print_ecdh_info(gnutls_session_t session, const char *str, int print if (!print) return; - printf("- %sEC Diffie-Hellman parameters\n", str); + log_msg(stdout, "- %sEC Diffie-Hellman parameters\n", str); curve = gnutls_ecc_curve_get(session); - printf(" - Using curve: %s\n", gnutls_ecc_curve_get_name(curve)); - printf(" - Curve size: %d bits\n", + log_msg(stdout, " - Using curve: %s\n", gnutls_ecc_curve_get_name(curve)); + log_msg(stdout, " - Curve size: %d bits\n", gnutls_ecc_curve_get_size(curve) * 8); } @@ -396,13 +397,13 @@ int print_info(gnutls_session_t session, int verbose, int flags) int rc; desc = gnutls_session_get_desc(session); - printf("- Description: %s\n", desc); + log_msg(stdout, "- Description: %s\n", desc); gnutls_free(desc); /* print session ID */ gnutls_session_get_id(session, session_id, &session_id_size); if (session_id_size > 0) { - printf("- Session ID: %s\n", + log_msg(stdout, "- Session ID: %s\n", raw_to_string(session_id, session_id_size)); } @@ -426,7 +427,7 @@ int print_info(gnutls_session_t session, int verbose, int flags) * side. */ if (gnutls_srp_server_get_username(session) != NULL) - printf("- SRP authentication. Connected as '%s'\n", + log_msg(stdout, "- SRP authentication. Connected as '%s'\n", gnutls_srp_server_get_username(session)); break; #endif @@ -435,12 +436,12 @@ int print_info(gnutls_session_t session, int verbose, int flags) /* This returns NULL in server side. */ if (gnutls_psk_client_get_hint(session) != NULL) - printf("- PSK authentication. PSK hint '%s'\n", + log_msg(stdout, "- PSK authentication. PSK hint '%s'\n", gnutls_psk_client_get_hint(session)); /* This returns NULL in client side. */ if (gnutls_psk_server_get_username(session) != NULL) - printf("- PSK authentication. Connected as '%s'\n", + log_msg(stdout, "- PSK authentication. Connected as '%s'\n", gnutls_psk_server_get_username(session)); if (kx == GNUTLS_KX_DHE_PSK) print_dh_info(session, "Ephemeral ", verbose); @@ -449,7 +450,7 @@ int print_info(gnutls_session_t session, int verbose, int flags) break; #endif case GNUTLS_CRD_IA: - printf("- TLS/IA authentication\n"); + log_msg(stdout, "- TLS/IA authentication\n"); break; case GNUTLS_CRD_CERTIFICATE: { @@ -460,13 +461,13 @@ int print_info(gnutls_session_t session, int verbose, int flags) /* This fails in client side */ if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0) { - printf("- Given server name[%d]: %s\n", + log_msg(stdout, "- Given server name[%d]: %s\n", type, dns); } } if ((flags & P_WAIT_FOR_CERT) && gnutls_certificate_get_ours(session) == 0) - printf("- No certificate was sent to peer\n"); + log_msg(stdout, "- No certificate was sent to peer\n"); if (flags& P_PRINT_CERT) print_cert_info(session, verbose, (flags&P_PRINT_CERT)); @@ -483,18 +484,18 @@ int print_info(gnutls_session_t session, int verbose, int flags) version = gnutls_protocol_get_version(session); tmp = SU(gnutls_protocol_get_name(version)); - printf("- Version: %s\n", tmp); + log_msg(stdout, "- Version: %s\n", tmp); if (version < GNUTLS_TLS1_3) { tmp = SU(gnutls_kx_get_name(kx)); - printf("- Key Exchange: %s\n", tmp); + log_msg(stdout, "- Key Exchange: %s\n", tmp); } if (gnutls_sign_algorithm_get(session) != GNUTLS_SIGN_UNKNOWN) { tmp = SU(gnutls_sign_get_name (gnutls_sign_algorithm_get(session))); - printf("- Server Signature: %s\n", tmp); + log_msg(stdout, "- Server Signature: %s\n", tmp); } if (gnutls_sign_algorithm_get_client(session) != @@ -502,41 +503,41 @@ int print_info(gnutls_session_t session, int verbose, int flags) tmp = SU(gnutls_sign_get_name (gnutls_sign_algorithm_get_client(session))); - printf("- Client Signature: %s\n", tmp); + log_msg(stdout, "- Client Signature: %s\n", tmp); } tmp = SU(gnutls_cipher_get_name(gnutls_cipher_get(session))); - printf("- Cipher: %s\n", tmp); + log_msg(stdout, "- Cipher: %s\n", tmp); tmp = SU(gnutls_mac_get_name(gnutls_mac_get(session))); - printf("- MAC: %s\n", tmp); + log_msg(stdout, "- MAC: %s\n", tmp); } - printf("- Options:"); + log_msg(stdout, "- Options:"); if (gnutls_session_ext_master_secret_status(session)!=0) - printf(" extended master secret,"); + log_msg(stdout, " extended master secret,"); if (gnutls_safe_renegotiation_status(session)!=0) - printf(" safe renegotiation,"); + log_msg(stdout, " safe renegotiation,"); if (gnutls_session_etm_status(session)!=0) - printf(" EtM,"); + log_msg(stdout, " EtM,"); #ifdef ENABLE_OCSP if (gnutls_ocsp_status_request_is_checked(session, GNUTLS_OCSP_SR_IS_AVAIL)!=0) { - printf(" OCSP status request%s,", gnutls_ocsp_status_request_is_checked(session,0)!=0?"":"[ignored]"); + log_msg(stdout, " OCSP status request%s,", gnutls_ocsp_status_request_is_checked(session,0)!=0?"":"[ignored]"); } #endif - printf("\n"); + log_msg(stdout, "\n"); #ifdef ENABLE_DTLS_SRTP rc = gnutls_srtp_get_selected_profile(session, &srtp_profile); if (rc == 0) - printf("- SRTP profile: %s\n", + log_msg(stdout, "- SRTP profile: %s\n", gnutls_srtp_get_profile_name(srtp_profile)); #endif #ifdef ENABLE_ALPN rc = gnutls_alpn_get_selected_protocol(session, &p); if (rc == 0) - printf("- Application protocol: %.*s\n", p.size, p.data); + log_msg(stdout, "- Application protocol: %.*s\n", p.size, p.data); #endif if (verbose) { @@ -551,10 +552,10 @@ int print_info(gnutls_session_t session, int verbose, int flags) else { size_t i; - printf("- Channel binding 'tls-unique': "); + log_msg(stdout, "- Channel binding 'tls-unique': "); for (i = 0; i < cb.size; i++) - printf("%02x", cb.data[i]); - printf("\n"); + log_msg(stdout, "%02x", cb.data[i]); + log_msg(stdout, "\n"); gnutls_free(cb.data); } } @@ -579,7 +580,7 @@ void print_cert_info2(gnutls_session_t session, int verbose, FILE *out, int prin flag = GNUTLS_CRT_PRINT_COMPACT; if (gnutls_certificate_client_get_request_status(session) != 0) { - printf("- Server has requested a certificate.\n"); + log_msg(stdout, "- Server has requested a certificate.\n"); print_crt_status = 1; } @@ -597,7 +598,7 @@ void print_cert_info_compact(gnutls_session_t session) int verbose = 0; if (gnutls_certificate_client_get_request_status(session) != 0) { - printf("- Server has requested a certificate.\n"); + log_msg(stdout, "- Server has requested a certificate.\n"); verbose = 1; } @@ -626,7 +627,7 @@ void print_list(const char *priorities, int verbose) const unsigned int *list; if (priorities != NULL) { - printf("Cipher suites for %s\n", priorities); + log_msg(stdout, "Cipher suites for %s\n", priorities); ret = gnutls_priority_init(&pcache, priorities, &err); if (ret < 0) { @@ -652,13 +653,13 @@ void print_list(const char *priorities, int verbose) NULL, &version); if (name != NULL) - printf("%-50s\t0x%02x, 0x%02x\t%s\n", + log_msg(stdout, "%-50s\t0x%02x, 0x%02x\t%s\n", name, (unsigned char) id[0], (unsigned char) id[1], gnutls_protocol_get_name(version)); } - printf("\n"); + log_msg(stdout, "\n"); #if 0 { ret = @@ -666,17 +667,17 @@ void print_list(const char *priorities, int verbose) &list, GNUTLS_CTYPE_CLIENT); - printf("Certificate types: "); + log_msg(stdout, "Certificate types: "); if (ret == 0) - printf("none\n"); + log_msg(stdout, "none\n"); for (i = 0; i < (unsigned) ret; i++) { - printf("CTYPE-%s", + log_msg(stdout, "CTYPE-%s", gnutls_certificate_type_get_name (list[i])); if (i + 1 != (unsigned) ret) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } #endif @@ -684,64 +685,64 @@ void print_list(const char *priorities, int verbose) { ret = gnutls_priority_protocol_list(pcache, &list); - printf("Protocols: "); + log_msg(stdout, "Protocols: "); if (ret == 0) - printf("none\n"); + log_msg(stdout, "none\n"); for (i = 0; i < (unsigned) ret; i++) { - printf("VERS-%s", + log_msg(stdout, "VERS-%s", gnutls_protocol_get_name(list[i])); if (i + 1 != (unsigned) ret) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } { ret = gnutls_priority_cipher_list(pcache, &list); - printf("Ciphers: "); + log_msg(stdout, "Ciphers: "); if (ret == 0) - printf("none\n"); + log_msg(stdout, "none\n"); for (i = 0; i < (unsigned) ret; i++) { - printf("%s", + log_msg(stdout, "%s", gnutls_cipher_get_name(list[i])); if (i + 1 != (unsigned) ret) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } { ret = gnutls_priority_mac_list(pcache, &list); - printf("MACs: "); + log_msg(stdout, "MACs: "); if (ret == 0) - printf("none\n"); + log_msg(stdout, "none\n"); for (i = 0; i < (unsigned) ret; i++) { - printf("%s", + log_msg(stdout, "%s", gnutls_mac_get_name(list[i])); if (i + 1 != (unsigned) ret) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } { ret = gnutls_priority_kx_list(pcache, &list); - printf("Key Exchange Algorithms: "); + log_msg(stdout, "Key Exchange Algorithms: "); if (ret == 0) - printf("none\n"); + log_msg(stdout, "none\n"); for (i = 0; i < (unsigned) ret; i++) { - printf("%s", + log_msg(stdout, "%s", gnutls_kx_get_name(list[i])); if (i + 1 != (unsigned) ret) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } @@ -749,33 +750,33 @@ void print_list(const char *priorities, int verbose) ret = gnutls_priority_group_list(pcache, &list); - printf("Groups: "); + log_msg(stdout, "Groups: "); if (ret == 0) - printf("none\n"); + log_msg(stdout, "none\n"); for (i = 0; i < (unsigned) ret; i++) { - printf("GROUP-%s", + log_msg(stdout, "GROUP-%s", gnutls_group_get_name(list[i])); if (i + 1 != (unsigned) ret) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } { ret = gnutls_priority_sign_list(pcache, &list); - printf("PK-signatures: "); + log_msg(stdout, "PK-signatures: "); if (ret == 0) - printf("none\n"); + log_msg(stdout, "none\n"); for (i = 0; i < (unsigned) ret; i++) { - printf("SIGN-%s", + log_msg(stdout, "SIGN-%s", gnutls_sign_algorithm_get_name(list [i])); if (i + 1 != (unsigned) ret) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } @@ -783,99 +784,99 @@ void print_list(const char *priorities, int verbose) return; } - printf("Cipher suites:\n"); + log_msg(stdout, "Cipher suites:\n"); for (i = 0; (name = gnutls_cipher_suite_info (i, id, &kx, &cipher, &mac, &version)); i++) { - printf("%-50s\t0x%02x, 0x%02x\t%s\n", + log_msg(stdout, "%-50s\t0x%02x, 0x%02x\t%s\n", name, (unsigned char) id[0], (unsigned char) id[1], gnutls_protocol_get_name(version)); if (verbose) - printf - ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n", + log_msg + (stdout, "\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n", gnutls_kx_get_name(kx), gnutls_cipher_get_name(cipher), gnutls_mac_get_name(mac)); } - printf("\n"); + log_msg(stdout, "\n"); { const gnutls_certificate_type_t *p = gnutls_certificate_type_list(); - printf("Certificate types: "); + log_msg(stdout, "Certificate types: "); for (; *p; p++) { - printf("CTYPE-%s", + log_msg(stdout, "CTYPE-%s", gnutls_certificate_type_get_name(*p)); if (*(p + 1)) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } { const gnutls_protocol_t *p = gnutls_protocol_list(); - printf("Protocols: "); + log_msg(stdout, "Protocols: "); for (; *p; p++) { - printf("VERS-%s", gnutls_protocol_get_name(*p)); + log_msg(stdout, "VERS-%s", gnutls_protocol_get_name(*p)); if (*(p + 1)) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } { const gnutls_cipher_algorithm_t *p = gnutls_cipher_list(); - printf("Ciphers: "); + log_msg(stdout, "Ciphers: "); for (; *p; p++) { - printf("%s", gnutls_cipher_get_name(*p)); + log_msg(stdout, "%s", gnutls_cipher_get_name(*p)); if (*(p + 1)) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } { const gnutls_mac_algorithm_t *p = gnutls_mac_list(); - printf("MACs: "); + log_msg(stdout, "MACs: "); for (; *p; p++) { - printf("%s", gnutls_mac_get_name(*p)); + log_msg(stdout, "%s", gnutls_mac_get_name(*p)); if (*(p + 1)) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } { const gnutls_digest_algorithm_t *p = gnutls_digest_list(); - printf("Digests: "); + log_msg(stdout, "Digests: "); for (; *p; p++) { - printf("%s", gnutls_digest_get_name(*p)); + log_msg(stdout, "%s", gnutls_digest_get_name(*p)); if (*(p + 1)) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } { const gnutls_kx_algorithm_t *p = gnutls_kx_list(); - printf("Key exchange algorithms: "); + log_msg(stdout, "Key exchange algorithms: "); for (; *p; p++) { - printf("%s", gnutls_kx_get_name(*p)); + log_msg(stdout, "%s", gnutls_kx_get_name(*p)); if (*(p + 1)) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } @@ -883,53 +884,53 @@ void print_list(const char *priorities, int verbose) const gnutls_compression_method_t *p = gnutls_compression_list(); - printf("Compression: "); + log_msg(stdout, "Compression: "); for (; *p; p++) { - printf("COMP-%s", gnutls_compression_get_name(*p)); + log_msg(stdout, "COMP-%s", gnutls_compression_get_name(*p)); if (*(p + 1)) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } { const gnutls_group_t *p = gnutls_group_list(); - printf("Groups: "); + log_msg(stdout, "Groups: "); for (; *p; p++) { - printf("GROUP-%s", gnutls_group_get_name(*p)); + log_msg(stdout, "GROUP-%s", gnutls_group_get_name(*p)); if (*(p + 1)) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } { const gnutls_pk_algorithm_t *p = gnutls_pk_list(); - printf("Public Key Systems: "); + log_msg(stdout, "Public Key Systems: "); for (; *p; p++) { - printf("%s", gnutls_pk_algorithm_get_name(*p)); + log_msg(stdout, "%s", gnutls_pk_algorithm_get_name(*p)); if (*(p + 1)) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } { const gnutls_sign_algorithm_t *p = gnutls_sign_list(); - printf("PK-signatures: "); + log_msg(stdout, "PK-signatures: "); for (; *p; p++) { - printf("SIGN-%s", + log_msg(stdout, "SIGN-%s", gnutls_sign_algorithm_get_name(*p)); if (*(p + 1)) - printf(", "); + log_msg(stdout, ", "); else - printf("\n"); + log_msg(stdout, "\n"); } } } @@ -1069,16 +1070,16 @@ pin_callback(void *user, int attempt, const char *token_url, if (flags & GNUTLS_PIN_FINAL_TRY) { cache = 0; - printf("*** This is the final try before locking!\n"); + log_msg(stdout, "*** This is the final try before locking!\n"); } if (flags & GNUTLS_PIN_COUNT_LOW) { cache = 0; - printf("*** Only few tries left before locking!\n"); + log_msg(stdout, "*** Only few tries left before locking!\n"); } if (flags & GNUTLS_PIN_WRONG) { cache = 0; - printf("*** Wrong PIN has been provided!\n"); + log_msg(stdout, "*** Wrong PIN has been provided!\n"); } if (cache > 0 && cached_url != NULL) { @@ -1166,7 +1167,7 @@ token_callback(void *user, const char *label, const unsigned retry) fprintf(stderr, "Could not find token %s\n", label); return -1; } - printf("Please insert token '%s' in slot and press enter\n", + log_msg(stdout, "Please insert token '%s' in slot and press enter\n", label); if (fgets(buf, sizeof(buf), stdin) == NULL) { fprintf(stderr, "error reading input\n"); @@ -1200,3 +1201,23 @@ void sockets_init(void) signal(SIGPIPE, SIG_IGN); #endif } + + +int log_msg(FILE *file, const char *message, ...) +{ + va_list args; + int rv; + + va_start(args, message); + + rv = vfprintf(logfile ? logfile : file, message, args); + + va_end(args); + + return rv; +} + +void log_set(FILE *file) +{ + logfile = file; +} diff --git a/src/common.h b/src/common.h index 2d2a69cc0f..1c2a0bc197 100644 --- a/src/common.h +++ b/src/common.h @@ -62,6 +62,9 @@ int print_info(gnutls_session_t state, int verbose, int flags); void print_cert_info(gnutls_session_t, int flag, int print_cert); void print_cert_info_compact(gnutls_session_t session); +int log_msg(FILE *file, const char *message, ...) __attribute__((format(printf, 2, 3))); +void log_set(FILE *file); + void print_cert_info2(gnutls_session_t, int flag, FILE *fp, int print_cert); void print_list(const char *priorities, int verbose); diff --git a/src/socket.c b/src/socket.c index b65d585102..9ba784fa3a 100644 --- a/src/socket.c +++ b/src/socket.c @@ -37,6 +37,7 @@ #include <socket.h> #include <c-ctype.h> #include "sockets.h" +#include "common.h" #ifdef _WIN32 # undef endservent @@ -226,7 +227,7 @@ socket_starttls(socket_st * socket) if (strcasecmp(socket->app_proto, "smtp") == 0 || strcasecmp(socket->app_proto, "submission") == 0) { if (socket->verbose) - printf("Negotiating SMTP STARTTLS\n"); + log_msg(stdout, "Negotiating SMTP STARTTLS\n"); wait_for_text(socket, "220 ", 4); snprintf(buf, sizeof(buf), "EHLO %s\r\n", socket->hostname); @@ -236,7 +237,7 @@ socket_starttls(socket_st * socket) wait_for_text(socket, "220 ", 4); } else if (strcasecmp(socket->app_proto, "imap") == 0 || strcasecmp(socket->app_proto, "imap2") == 0) { if (socket->verbose) - printf("Negotiating IMAP STARTTLS\n"); + log_msg(stdout, "Negotiating IMAP STARTTLS\n"); send_line(socket, "a CAPABILITY\r\n"); wait_for_text(socket, "a OK", 4); @@ -244,7 +245,7 @@ socket_starttls(socket_st * socket) wait_for_text(socket, "a OK", 4); } else if (strcasecmp(socket->app_proto, "xmpp") == 0) { if (socket->verbose) - printf("Negotiating XMPP STARTTLS\n"); + log_msg(stdout, "Negotiating XMPP STARTTLS\n"); snprintf(buf, sizeof(buf), "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='%s' version='1.0'>\n", socket->hostname); send_line(socket, buf); @@ -253,13 +254,13 @@ socket_starttls(socket_st * socket) wait_for_text(socket, "<proceed", 8); } else if (strcasecmp(socket->app_proto, "ldap") == 0) { if (socket->verbose) - printf("Negotiating LDAP STARTTLS\n"); + log_msg(stdout, "Negotiating LDAP STARTTLS\n"); #define LDAP_STR "\x30\x1d\x02\x01\x01\x77\x18\x80\x16\x31\x2e\x33\x2e\x36\x2e\x31\x2e\x34\x2e\x31\x2e\x31\x34\x36\x36\x2e\x32\x30\x30\x33\x37" send(socket->fd, LDAP_STR, sizeof(LDAP_STR)-1, 0); wait_for_text(socket, NULL, 0); } else if (strcasecmp(socket->app_proto, "ftp") == 0 || strcasecmp(socket->app_proto, "ftps") == 0) { if (socket->verbose) - printf("Negotiating FTP STARTTLS\n"); + log_msg(stdout, "Negotiating FTP STARTTLS\n"); send_line(socket, "FEAT\r\n"); wait_for_text(socket, "211 ", 4); @@ -267,7 +268,7 @@ socket_starttls(socket_st * socket) wait_for_text(socket, "234", 3); } else if (strcasecmp(socket->app_proto, "lmtp") == 0) { if (socket->verbose) - printf("Negotiating LMTP STARTTLS\n"); + log_msg(stdout, "Negotiating LMTP STARTTLS\n"); wait_for_text(socket, "220 ", 4); snprintf(buf, sizeof(buf), "LHLO %s\r\n", socket->hostname); @@ -277,28 +278,28 @@ socket_starttls(socket_st * socket) wait_for_text(socket, "220 ", 4); } else if (strcasecmp(socket->app_proto, "pop3") == 0) { if (socket->verbose) - printf("Negotiating POP3 STARTTLS\n"); + log_msg(stdout, "Negotiating POP3 STARTTLS\n"); wait_for_text(socket, "+OK", 3); send_line(socket, "STLS\r\n"); wait_for_text(socket, "+OK", 3); } else if (strcasecmp(socket->app_proto, "nntp") == 0) { if (socket->verbose) - printf("Negotiating NNTP STARTTLS\n"); + log_msg(stdout, "Negotiating NNTP STARTTLS\n"); wait_for_text(socket, "200 ", 4); send_line(socket, "STARTTLS\r\n"); wait_for_text(socket, "382 ", 4); } else if (strcasecmp(socket->app_proto, "sieve") == 0) { if (socket->verbose) - printf("Negotiating Sieve STARTTLS\n"); + log_msg(stdout, "Negotiating Sieve STARTTLS\n"); wait_for_text(socket, "OK ", 3); send_line(socket, "STARTTLS\r\n"); wait_for_text(socket, "OK ", 3); } else if (strcasecmp(socket->app_proto, "postgres") == 0 || strcasecmp(socket->app_proto, "postgresql") == 0) { if (socket->verbose) - printf("Negotiating PostgreSQL STARTTLS\n"); + log_msg(stdout, "Negotiating PostgreSQL STARTTLS\n"); #define POSTGRES_STR "\x00\x00\x00\x08\x04\xD2\x16\x2F" send(socket->fd, POSTGRES_STR, sizeof(POSTGRES_STR)-1, 0); @@ -494,7 +495,7 @@ socket_open2(socket_st * hd, const char *hostname, const char *service, a_hostname = (char*)idna.data; if (msg != NULL) - printf("Resolving '%s:%s'...\n", a_hostname, service); + log_msg(stdout, "Resolving '%s:%s'...\n", a_hostname, service); /* get server name */ memset(&hints, 0, sizeof(hints)); @@ -543,11 +544,11 @@ socket_open2(socket_st * hd, const char *hostname, const char *service, hd->connect_addrlen = ptr->ai_addrlen; if (msg) - printf("%s '%s:%s' (TFO)...\n", msg, buffer, portname); + log_msg(stdout, "%s '%s:%s' (TFO)...\n", msg, buffer, portname); } else { if (msg) - printf("%s '%s:%s'...\n", msg, buffer, portname); + log_msg(stdout, "%s '%s:%s'...\n", msg, buffer, portname); if ((err = connect(sd, ptr->ai_addr, ptr->ai_addrlen)) < 0) continue; diff --git a/tests/Makefile.am b/tests/Makefile.am index 34c697f3d4..8f778f57e5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -467,7 +467,7 @@ dist_check_SCRIPTS += fastopen.sh pkgconfig.sh starttls.sh starttls-ftp.sh start ocsp-tests/ocsp-test cipher-listings.sh sni-hostname.sh server-multi-keys.sh \ psktool.sh ocsp-tests/ocsp-load-chain gnutls-cli-save-data.sh gnutls-cli-debug.sh \ sni-resume.sh ocsp-tests/ocsptool cert-reencoding.sh pkcs7-cat.sh long-crl.sh \ - serv-udp.sh + serv-udp.sh logfile-option.sh dist_check_SCRIPTS += gnutls-cli-self-signed.sh gnutls-cli-invalid-crl.sh diff --git a/tests/logfile-option.sh b/tests/logfile-option.sh new file mode 100755 index 0000000000..64fa232c8b --- /dev/null +++ b/tests/logfile-option.sh @@ -0,0 +1,113 @@ +#!/bin/sh + +# Copyright (C) 2010-2016 Free Software Foundation, Inc. +# +# Author: Nikos Mavrogiannopoulos +# +# This file is part of GnuTLS. +# +# GnuTLS is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# GnuTLS is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GnuTLS; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +srcdir="${srcdir:-.}" +SERV="${SERV:-../src/gnutls-serv${EXEEXT}}" +CLI="${CLI:-../src/gnutls-cli${EXEEXT}}" +unset RETCODE + +if ! test -x "${SERV}"; then + exit 77 +fi + +if ! test -x "${CLI}"; then + exit 77 +fi + +if test "${WINDIR}" != ""; then + exit 77 +fi + +if ! test -z "${VALGRIND}"; then + VALGRIND="${LIBTOOL:-libtool} --mode=execute ${VALGRIND} --error-exitcode=15" +fi + + +SERV="${SERV} -q" + +. "${srcdir}/scripts/common.sh" + +echo "Checking whether logfile option works." + +KEY1=${srcdir}/../doc/credentials/x509/key-rsa.pem +CERT1=${srcdir}/../doc/credentials/x509/cert-rsa.pem +OCSP1=${srcdir}/ocsp-tests/response1.der +PSK=${srcdir}/psk.passwd + +TMPFILE1=save-data1.$$.tmp +TMPFILE2=save-data2.$$.tmp + +eval "${GETPORT}" +launch_server $$ --echo --priority NORMAL:+ECDHE-PSK:+DHE-PSK:+PSK --pskpasswd=${PSK} +PID=$! +wait_server ${PID} + +${VALGRIND} "${CLI}" -p "${PORT}" 127.0.0.1 --priority NORMAL:+ECDHE-PSK:+DHE-PSK:+PSK --pskusername=jas --pskkey=9e32cf7786321a828ef7668f09fb35db </dev/null >${TMPFILE2} + +kill ${PID} +wait + +if test -f ${TMPFILE1};then + echo "Logfile should not be created!" + exit 1 +fi +if ! test -s ${TMPFILE2};then + echo "Stdout should not be empty!" + exit 1 +fi +if grep -q "Handshake was completed" ${TMPFILE2};then + echo "Find the expected output!" +else + echo "Cannot find the expected output!" + exit 1 +fi + +rm -f ${TMPFILE1} ${TMPFILE2} + +eval "${GETPORT}" +launch_server $$ --echo --priority NORMAL:+ECDHE-PSK:+DHE-PSK:+PSK --pskpasswd=${PSK} +PID=$! +wait_server ${PID} + +${VALGRIND} "${CLI}" -p "${PORT}" 127.0.0.1 --logfile ${TMPFILE1} --priority NORMAL:+ECDHE-PSK:+DHE-PSK:+PSK --pskusername=jas --pskkey=9e32cf7786321a828ef7668f09fb35db </dev/null >${TMPFILE2} + +kill ${PID} +wait + +if ! test -f ${TMPFILE1};then + echo "Logfile shoule be created!" + exit 1 +fi +if test -s ${TMPFILE2};then + echo "Stdout should be empty!" + exit 1 +fi + +if grep -q "Handshake was completed" ${TMPFILE1}; then + echo "Found the expected output!" +else + echo "Cannot find the expected output!" + exit 1 +fi +rm -f ${TMPFILE1} ${TMPFILE2} + +exit 0 |