X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Ftls-gnu.c;h=bbc75b68019ab3118a0880e4a29989667cbacbd5;hb=fc55624df0c1956b7b6b4ae35605a6b95704d022;hp=dc8cdab5c34f0c46d969e24dab30e57b5ec92155;hpb=7a501c874f028f689c44999ab05bb0d39da46941;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index dc8cdab5c..bbc75b680 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -648,7 +648,7 @@ if ((fd = Uopen(filename, O_RDONLY, 0)) >= 0) } m.size = statbuf.st_size; - if (!(m.data = malloc(m.size))) + if (!(m.data = store_malloc(m.size))) { fclose(fp); return tls_error_sys(US"malloc failed", errno, NULL, errstr); @@ -657,13 +657,13 @@ if ((fd = Uopen(filename, O_RDONLY, 0)) >= 0) { saved_errno = errno; fclose(fp); - free(m.data); + store_free(m.data); return tls_error_sys(US"fread failed", saved_errno, NULL, errstr); } fclose(fp); rc = gnutls_dh_params_import_pkcs3(dh_server_params, &m, GNUTLS_X509_FMT_PEM); - free(m.data); + store_free(m.data); if (rc) return tls_error_gnu(US"gnutls_dh_params_import_pkcs3", rc, host, errstr); DEBUG(D_tls) debug_printf("read D-H parameters from file \"%s\"\n", filename); @@ -736,25 +736,25 @@ if (rc < 0) return tls_error_gnu(US"gnutls_dh_params_export_pkcs3(NULL) sizing", rc, host, errstr); m.size = sz; - if (!(m.data = malloc(m.size))) + if (!(m.data = store_malloc(m.size))) return tls_error_sys(US"memory allocation failed", errno, NULL, errstr); /* this will return a size 1 less than the allocation size above */ if ((rc = gnutls_dh_params_export_pkcs3(dh_server_params, GNUTLS_X509_FMT_PEM, m.data, &sz))) { - free(m.data); + store_free(m.data); return tls_error_gnu(US"gnutls_dh_params_export_pkcs3() real", rc, host, errstr); } m.size = sz; /* shrink by 1, probably */ if ((sz = write_to_fd_buf(fd, m.data, (size_t) m.size)) != m.size) { - free(m.data); + store_free(m.data); return tls_error_sys(US"TLS cache write D-H params failed", errno, NULL, errstr); } - free(m.data); + store_free(m.data); if ((sz = write_to_fd_buf(fd, US"\n", 1)) != 1) return tls_error_sys(US"TLS cache write D-H params final newline failed", errno, NULL, errstr); @@ -1143,6 +1143,14 @@ else #endif gnutls_certificate_set_x509_trust_file(state->x509_cred, CS state->exp_tls_verify_certificates, GNUTLS_X509_FMT_PEM); + +#ifdef SUPPORT_CA_DIR + /* Mimic the behaviour with OpenSSL of not advertising a usable-cert list + when using the directory-of-certs config model. */ + + if ((statbuf.st_mode & S_IFMT) == S_IFDIR) + gnutls_certificate_send_x509_rdn_sequence(state->session, 1); +#endif } if (cert_count < 0) @@ -1324,7 +1332,7 @@ if (host) several in parallel. */ int old_pool = store_pool; store_pool = POOL_PERM; - state = store_get(sizeof(exim_gnutls_state_st)); + state = store_get(sizeof(exim_gnutls_state_st), FALSE); store_pool = old_pool; memcpy(state, &exim_gnutls_state_init, sizeof(exim_gnutls_state_init)); @@ -1621,7 +1629,7 @@ if (rc != GNUTLS_E_SHORT_MEMORY_BUFFER) exim_gnutls_peer_err(US"getting size for cert DN failed"); return FAIL; /* should not happen */ } -dn_buf = store_get_perm(sz); +dn_buf = store_get_perm(sz, TRUE); /* tainted */ rc = gnutls_x509_crt_get_dn(crt, CS dn_buf, &sz); exim_gnutls_peer_err(US"failed to extract certificate DN [gnutls_x509_crt_get_dn(cert 0)]"); @@ -1701,8 +1709,8 @@ else for(nrec = 0; state->dane_data_len[nrec]; ) nrec++; nrec++; - dd = store_get(nrec * sizeof(uschar *)); - ddl = store_get(nrec * sizeof(int)); + dd = store_get(nrec * sizeof(uschar *), FALSE); + ddl = store_get(nrec * sizeof(int), FALSE); nrec--; if ((rc = dane_state_init(&s, 0))) @@ -1930,13 +1938,12 @@ uschar * dummy_errstr; rc = gnutls_server_name_get(session, sni_name, &data_len, &sni_type, 0); if (rc != GNUTLS_E_SUCCESS) { - DEBUG(D_tls) { + DEBUG(D_tls) if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) debug_printf("TLS: no SNI presented in handshake.\n"); else debug_printf("TLS failure: gnutls_server_name_get(): %s [%d]\n", gnutls_strerror(rc), rc); - } return 0; } @@ -1949,7 +1956,7 @@ if (sni_type != GNUTLS_NAME_DNS) /* We now have a UTF-8 string in sni_name */ old_pool = store_pool; store_pool = POOL_PERM; -state->received_sni = string_copyn(US sni_name, data_len); +state->received_sni = string_copy_taint(US sni_name, TRUE); store_pool = old_pool; /* We set this one now so that variable expansions below will work */ @@ -2384,8 +2391,8 @@ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT) ) if (rr->type == T_TLSA) i++; -dane_data = store_get(i * sizeof(uschar *)); -dane_data_len = store_get(i * sizeof(int)); +dane_data = store_get(i * sizeof(uschar *), FALSE); +dane_data_len = store_get(i * sizeof(int), FALSE); i = 0; for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; @@ -2393,6 +2400,7 @@ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; ) if (rr->type == T_TLSA && rr->size > 3) { const uschar * p = rr->data; +/*XXX need somehow to mark rr and its data as tainted. Doues this mean copying it? */ uint8_t usage = p[0], sel = p[1], type = p[2]; DEBUG(D_tls) @@ -2497,7 +2505,7 @@ if (gnutls_session_get_flags(session) & GNUTLS_SFLAGS_SESSION_TICKET) { open_db dbblock, * dbm_file; int dlen = sizeof(dbdata_tls_session) + tkt.size; - dbdata_tls_session * dt = store_get(dlen); + dbdata_tls_session * dt = store_get(dlen, TRUE); DEBUG(D_tls) debug_printf("session data size %u\n", (unsigned)tkt.size); memcpy(dt->session, tkt.data, tkt.size); @@ -2827,8 +2835,9 @@ void tls_close(void * ct_ctx, int shutdown) { exim_gnutls_state_st * state = ct_ctx ? ct_ctx : &state_server; +tls_support * tlsp = state->tlsp; -if (!state->tlsp || state->tlsp->active.sock < 0) return; /* TLS was not active */ +if (!tlsp || tlsp->active.sock < 0) return; /* TLS was not active */ if (shutdown) { @@ -2840,12 +2849,26 @@ if (shutdown) ALARM_CLR(0); } +if (!ct_ctx) /* server */ + { + receive_getc = smtp_getc; + receive_getbuf = smtp_getbuf; + receive_get_cache = smtp_get_cache; + receive_ungetc = smtp_ungetc; + receive_feof = smtp_feof; + receive_ferror = smtp_ferror; + receive_smtp_buffered = smtp_buffered; + } + gnutls_deinit(state->session); gnutls_certificate_free_credentials(state->x509_cred); +tlsp->active.sock = -1; +tlsp->active.tls_ctx = NULL; +/* Leave bits, peercert, cipher, peerdn, certificate_verified set, for logging */ +tls_channelbinding_b64 = NULL; + -state->tlsp->active.sock = -1; -state->tlsp->active.tls_ctx = NULL; if (state->xfer_buffer) store_free(state->xfer_buffer); memcpy(state, &exim_gnutls_state_init, sizeof(exim_gnutls_state_init)); } @@ -2895,28 +2918,7 @@ if (sigalrm_seen) else if (inbytes == 0) { DEBUG(D_tls) debug_printf("Got TLS_EOF\n"); - - receive_getc = smtp_getc; - receive_getbuf = smtp_getbuf; - receive_get_cache = smtp_get_cache; - receive_ungetc = smtp_ungetc; - receive_feof = smtp_feof; - receive_ferror = smtp_ferror; - receive_smtp_buffered = smtp_buffered; - - gnutls_deinit(state->session); - gnutls_certificate_free_credentials(state->x509_cred); - - state->session = NULL; - state->tlsp->active.sock = -1; - state->tlsp->active.tls_ctx = NULL; - state->tlsp->bits = 0; - state->tlsp->certificate_verified = FALSE; - tls_channelbinding_b64 = NULL; - state->tlsp->cipher = NULL; - state->tlsp->peercert = NULL; - state->tlsp->peerdn = NULL; - + tls_close(NULL, TLS_NO_SHUTDOWN); return FALSE; }