X-Git-Url: https://ruderich.org/simon/gitweb/?a=blobdiff_plain;f=src%2Fconnection.c;h=28f2e699f1d68ae2a41e7d3a36c4cf0f3adb03c1;hb=28bc2ca1129818da944dcd5f2073cffdc497065c;hp=170302c9fdaf9894267c91da2ebd4934a27a6843;hpb=f3ca90e517a9ae54e831e5a5b91fcc2afb9df5bf;p=tlsproxy%2Ftlsproxy.git diff --git a/src/connection.c b/src/connection.c index 170302c..28f2e69 100644 --- a/src/connection.c +++ b/src/connection.c @@ -59,6 +59,10 @@ static int initialize_tls_session_client(int peer_socket, static int initialize_tls_session_server(int peer_socket, gnutls_session_t *session, gnutls_certificate_credentials_t *x509_cred); +static int initialize_tls_session_both(int flags, + int peer_socket, + gnutls_session_t *session, + gnutls_certificate_credentials_t *x509_cred); static int fdopen_read_write(int socket, FILE **read_fd, FILE **write_fd); static int read_http_request(FILE *client_fd, char *request, size_t length); @@ -313,7 +317,16 @@ out: /* Close TLS sessions if necessary. Use GNUTLS_SHUT_RDWR so the data is * reliable transmitted. */ if (server_session_started) { - gnutls_bye(server_session, GNUTLS_SHUT_RDWR); + /* Recent gnutls-serv (used in the test-suite) won't terminate the + * connection when gnutls_bye(session, GNUTLS_SHUT_RDWR) is used + * before any other data was received. If the validation failed just + * close the connection without waiting for data, we won't read it + * anyway. + * + * For verified connections GNUTLS_SHUT_RDWR is important or we might + * lose data. */ + gnutls_bye(server_session, validation_failed ? GNUTLS_SHUT_WR + : GNUTLS_SHUT_RDWR); } if (client_session_started) { gnutls_bye(client_session, GNUTLS_SHUT_RDWR); @@ -385,12 +398,12 @@ static int initialize_tls_session_client(int peer_socket, /* Load proxy CA file, this CA "list" is send to the client. */ if (!use_invalid_cert) { result = gnutls_certificate_set_x509_trust_file(*x509_cred, - PROXY_CA_FILE, + PROXY_CA_PATH, GNUTLS_X509_FMT_PEM); if (result <= 0) { LOG(ERROR, "initialize_tls_session_client(): can't read CA file: '%s'", - PROXY_CA_FILE); + PROXY_CA_PATH); gnutls_certificate_free_credentials(*x509_cred); return -1; } @@ -401,21 +414,22 @@ static int initialize_tls_session_client(int peer_socket, /* And certificate for this website and proxy's private key. */ if (!use_invalid_cert) { result = gnutls_certificate_set_x509_key_file(*x509_cred, - path, PROXY_KEY_FILE, + path, + PROXY_KEY_PATH, GNUTLS_X509_FMT_PEM); /* If the invalid hostname was specified load our special "invalid" * certificate. */ } else { result = gnutls_certificate_set_x509_key_file(*x509_cred, - PROXY_INVALID_CERT_FILE, - PROXY_KEY_FILE, + PROXY_INVALID_CERT_PATH, + PROXY_KEY_PATH, GNUTLS_X509_FMT_PEM); } if (result != GNUTLS_E_SUCCESS) { LOG(ERROR, "initialize_tls_session_client(): " "can't read server certificate ('%s') or key file ('%s'): %s", - path, PROXY_KEY_FILE, gnutls_strerror(result)); + path, PROXY_KEY_PATH, gnutls_strerror(result)); gnutls_certificate_free_credentials(*x509_cred); /* Could be a missing certificate. */ return -2; @@ -423,37 +437,8 @@ static int initialize_tls_session_client(int peer_socket, gnutls_certificate_set_dh_params(*x509_cred, global_tls_dh_params); - result = gnutls_init(session, GNUTLS_SERVER); - if (result != GNUTLS_E_SUCCESS) { - LOG(ERROR, - "initialize_tls_session_client(): gnutls_init(): %s", - gnutls_strerror(result)); - gnutls_certificate_free_credentials(*x509_cred); - return -1; - } - result = gnutls_priority_set(*session, global_tls_priority_cache); - if (result != GNUTLS_E_SUCCESS) { - LOG(ERROR, - "initialize_tls_session_client(): gnutls_priority_set(): %s", - gnutls_strerror(result)); - gnutls_deinit(*session); - gnutls_certificate_free_credentials(*x509_cred); - return -1; - } - result = gnutls_credentials_set(*session, - GNUTLS_CRD_CERTIFICATE, *x509_cred); - if (result != GNUTLS_E_SUCCESS) { - LOG(ERROR, - "initialize_tls_session_client(): gnutls_credentials_set(): %s", - gnutls_strerror(result)); - gnutls_deinit(*session); - gnutls_certificate_free_credentials(*x509_cred); - return -1; - } - - gnutls_transport_set_ptr(*session, (gnutls_transport_ptr_t)peer_socket); - - return 0; + return initialize_tls_session_both(GNUTLS_SERVER, + peer_socket, session, x509_cred); } static int initialize_tls_session_server(int peer_socket, gnutls_session_t *session, @@ -469,10 +454,19 @@ static int initialize_tls_session_server(int peer_socket, return -1; } - result = gnutls_init(session, GNUTLS_CLIENT); + return initialize_tls_session_both(GNUTLS_CLIENT, + peer_socket, session, x509_cred); +} +static int initialize_tls_session_both(int flags, + int peer_socket, + gnutls_session_t *session, + gnutls_certificate_credentials_t *x509_cred) { + int result; + + result = gnutls_init(session, flags); if (result != GNUTLS_E_SUCCESS) { LOG(ERROR, - "initialize_tls_session_server(): gnutls_init(): %s", + "initialize_tls_session_both(): gnutls_init(): %s", gnutls_strerror(result)); gnutls_certificate_free_credentials(*x509_cred); return -1; @@ -480,7 +474,7 @@ static int initialize_tls_session_server(int peer_socket, result = gnutls_priority_set(*session, global_tls_priority_cache); if (result != GNUTLS_E_SUCCESS) { LOG(ERROR, - "initialize_tls_session_server(): gnutls_priority_set(): %s", + "initialize_tls_session_both(): gnutls_priority_set(): %s", gnutls_strerror(result)); gnutls_deinit(*session); gnutls_certificate_free_credentials(*x509_cred); @@ -490,7 +484,7 @@ static int initialize_tls_session_server(int peer_socket, GNUTLS_CRD_CERTIFICATE, *x509_cred); if (result != GNUTLS_E_SUCCESS) { LOG(ERROR, - "initialize_tls_session_server(): gnutls_credentials_set(): %s", + "initialize_tls_session_both(): gnutls_credentials_set(): %s", gnutls_strerror(result)); gnutls_deinit(*session); gnutls_certificate_free_credentials(*x509_cred);