}
else if (exp_tls_dhparam[0] != '/')
{
- m.data = US std_dh_prime_named(exp_tls_dhparam);
- if (m.data == NULL)
+ if (!(m.data = US std_dh_prime_named(exp_tls_dhparam)))
return tls_error(US"No standard prime named", CS exp_tls_dhparam, NULL);
m.size = Ustrlen(m.data);
}
/* Open the cache file for reading and if successful, read it and set up the
parameters. */
-fd = Uopen(filename, O_RDONLY, 0);
-if (fd >= 0)
+if ((fd = Uopen(filename, O_RDONLY, 0)) >= 0)
{
struct stat statbuf;
FILE *fp;
(void)close(fd);
return tls_error(US"TLS cache not a file", NULL, NULL);
}
- fp = fdopen(fd, "rb");
- if (!fp)
+ if (!(fp = fdopen(fd, "rb")))
{
saved_errno = errno;
(void)close(fd);
}
m.size = statbuf.st_size;
- m.data = malloc(m.size);
- if (m.data == NULL)
+ if (!(m.data = malloc(m.size)))
{
fclose(fp);
return tls_error(US"malloc failed", strerror(errno), NULL);
}
- sz = fread(m.data, m.size, 1, fp);
- if (!sz)
+ if (!(sz = fread(m.data, m.size, 1, fp)))
{
saved_errno = errno;
fclose(fp);
CS filename, NULL);
temp_fn = string_copy(US "%s.XXXXXXX");
- fd = mkstemp(CS temp_fn); /* modifies temp_fn */
- if (fd < 0)
+ if ((fd = mkstemp(CS temp_fn)) < 0) /* modifies temp_fn */
return tls_error(US"Unable to open temp file", strerror(errno), NULL);
(void)fchown(fd, exim_uid, exim_gid); /* Probably not necessary */
if (rc != GNUTLS_E_SHORT_MEMORY_BUFFER)
exim_gnutls_err_check(US"gnutls_dh_params_export_pkcs3(NULL) sizing");
m.size = sz;
- m.data = malloc(m.size);
- if (m.data == NULL)
+ if (!(m.data = malloc(m.size)))
return tls_error(US"memory allocation failed", strerror(errno), NULL);
+
/* this will return a size 1 less than the allocation size above */
rc = gnutls_dh_params_export_pkcs3(dh_server_params, GNUTLS_X509_FMT_PEM,
m.data, &sz);
}
m.size = sz; /* shrink by 1, probably */
- sz = write_to_fd_buf(fd, m.data, (size_t) m.size);
- if (sz != m.size)
+ if ((sz = write_to_fd_buf(fd, m.data, (size_t) m.size)) != m.size)
{
free(m.data);
return tls_error(US"TLS cache write D-H params failed",
strerror(errno), NULL);
}
free(m.data);
- sz = write_to_fd_buf(fd, US"\n", 1);
- if (sz != 1)
+ if ((sz = write_to_fd_buf(fd, US"\n", 1)) != 1)
return tls_error(US"TLS cache write D-H params final newline failed",
strerror(errno), NULL);
- rc = close(fd);
- if (rc)
- return tls_error(US"TLS cache write close() failed",
- strerror(errno), NULL);
+ if ((rc = close(fd)))
+ return tls_error(US"TLS cache write close() failed", strerror(errno), NULL);
if (Urename(temp_fn, filename) < 0)
return tls_error(string_sprintf("failed to rename \"%s\" as \"%s\"",
if (rc != GNUTLS_E_SUCCESS)
{
- tls_error(US"gnutls_handshake",
- sigalrm_seen ? "timed out" : gnutls_strerror(rc), NULL);
/* It seems that, except in the case of a timeout, we have to close the
connection right here; otherwise if the other end is running OpenSSL it hangs
until the server times out. */
- if (!sigalrm_seen)
+ if (sigalrm_seen)
+ {
+ tls_error(US"gnutls_handshake", "timed out", NULL);
+ gnutls_db_remove_session(state->session);
+ }
+ else
{
+ tls_error(US"gnutls_handshake", gnutls_strerror(rc), NULL);
+ (void) gnutls_alert_send_appropriate(state->session, rc);
+ gnutls_deinit(state->session);
+ gnutls_certificate_free_credentials(state->x509_cred);
+ millisleep(500);
+ shutdown(state->fd_out, SHUT_WR);
+ for (rc = 1024; fgetc(smtp_in) != EOF && rc > 0; ) rc--; /* drain skt */
(void)fclose(smtp_out);
(void)fclose(smtp_in);
+ smtp_out = smtp_in = NULL;
}
return FAIL;
/* Figure out peer DN, and if authenticated, etc. */
-rc = peer_status(state);
-if (rc != OK) return rc;
+if ((rc = peer_status(state)) != OK) return rc;
/* Sets various Exim expansion variables; always safe within server */
alarm(0);
if (rc != GNUTLS_E_SUCCESS)
- return tls_error(US"gnutls_handshake",
- sigalrm_seen ? "timed out" : gnutls_strerror(rc), state->host);
+ if (sigalrm_seen)
+ {
+ gnutls_alert_send(state->session, GNUTLS_AL_FATAL, GNUTLS_A_USER_CANCELED);
+ return tls_error(US"gnutls_handshake", "timed out", state->host);
+ }
+ else
+ return tls_error(US"gnutls_handshake", gnutls_strerror(rc), state->host);
DEBUG(D_tls) debug_printf("gnutls_handshake was successful\n");
}
gnutls_deinit(state->session);
+gnutls_certificate_free_credentials(state->x509_cred);
+
state->tlsp->active = -1;
memcpy(state, &exim_gnutls_state_init, sizeof(exim_gnutls_state_init));
ssl_xfer_buffer_size);
alarm(0);
- /* A zero-byte return appears to mean that the TLS session has been
+ /* Timeouts do not get this far; see command_timeout_handler().
+ A zero-byte return appears to mean that the TLS session has been
closed down, not that the socket itself has been closed down. Revert to
non-TLS handling. */
- if (inbytes == 0)
+ if (sigalrm_seen)
+ {
+ DEBUG(D_tls) debug_printf("Got tls read timeout\n");
+ state->xfer_error = 1;
+ return EOF;
+ }
+
+ else if (inbytes == 0)
{
DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
receive_smtp_buffered = smtp_buffered;
gnutls_deinit(state->session);
+ gnutls_certificate_free_credentials(state->x509_cred);
+
state->session = NULL;
state->tlsp->active = -1;
state->tlsp->bits = 0;
return state->xfer_buffer[state->xfer_buffer_lwm++];
}
-#ifndef DISABLE_DKIM
void
tls_get_cache()
{
+#ifndef DISABLE_DKIM
exim_gnutls_state_st * state = &state_server;
int n = state->xfer_buffer_hwm - state->xfer_buffer_lwm;
if (n > 0)
dkim_exim_verify_feed(state->xfer_buffer+state->xfer_buffer_lwm, n);
-}
#endif
+}