/* Format string used to send HTTP/1.0 error responses to the client.
*
* %s is used 5 times, first is the error code, then additional headers, next
- * two are the error code (no %n$s!), the last is the message. */
+ * two are the error code (no %n$s which is not in C98!), the last is the
+ * message. */
#define HTTP_RESPONSE_FORMAT "HTTP/1.0 %s\r\n\
Content-Type: text/html; charset=US-ASCII\r\n\
%s\r\n\
const char msg[] = "Server certificate validation failed, check logs.";
int result;
+ ssize_t size_written;
char buffer[sizeof(HTTP_RESPONSE_FORMAT)
+ 3 * sizeof(error) + sizeof(msg)];
error, "", error, error, msg);
assert(result > 0 && (size_t)result < sizeof(buffer));
- gnutls_record_send(session, buffer, strlen(buffer));
+ size_written = gnutls_record_send(session, buffer, strlen(buffer));
+ if (size_written < 0) {
+ LOG(WARNING, "tls_send_invalid_cert_message(): "
+ "gnutls_record_send(): %s",
+ gnutls_strerror((int)size_written));
+ }
+ /* Just an error message, no need to check if everything was written. */
}
return -1;
}
if (size_read != size_written) {
- LOG(ERROR, "read_from_write_to(): only written %ld of %ld bytes!",
- (long int)size_written, (long int)size_read);
+ LOG(ERROR, "read_from_write_to(): only written %zu of %zu bytes!",
+ size_written, size_read);
return -1;
}
if (gnutls_record_get_max_size(server_session) < buffer_size) {
buffer_size = gnutls_record_get_max_size(server_session);
}
- LOG(DEBUG2, "transfer_data_tls(): suggested buffer size: %ld",
- (long int)buffer_size);
+ LOG(DEBUG2, "transfer_data_tls(): suggested buffer size: %zu",
+ buffer_size);
for (;;) {
int result = poll(fds, 2 /* fd count */, -1 /* no timeout */);
size_t buffer_size) {
ssize_t size_read;
ssize_t size_written;
- char buffer[16384];
+ char buffer[16384]; /* GnuTLS default maximum */
if (buffer_size > sizeof(buffer)) {
- LOG(WARNING, "read_from_write_to_tls(): reduced buffer size to %ld",
- (long int)(sizeof(buffer)));
+ LOG(WARNING, "read_from_write_to_tls(): reduced buffer size to %zu",
+ sizeof(buffer));
buffer_size = sizeof(buffer);
}
size_read = gnutls_record_recv(from, buffer, buffer_size);
if (size_read < 0) {
+ /* Allow rehandshakes. As handshakes might be insecure make sure that
+ * %SAFE_RENEGOTIATION is used in GnuTLS's priority string. */
+ if (size_read == GNUTLS_E_REHANDSHAKE) {
+ int result = gnutls_handshake(from);
+ if (result != GNUTLS_E_SUCCESS) {
+ LOG(WARNING, "server TLS rehandshake failed: %s",
+ gnutls_strerror(result));
+ return -1;
+ }
+ return 0;
+ }
+
LOG(WARNING, "read_from_write_to_tls(): gnutls_record_recv(): %s",
gnutls_strerror((int)size_read));
return -1;
return -1;
}
if (size_read != size_written) {
- LOG(ERROR, "read_from_write_to_tls(): only written %ld of %ld bytes!",
- (long int)size_written, (long int)size_read);
+ LOG(ERROR, "read_from_write_to_tls(): only written %zu of %zu bytes!",
+ size_written, size_read);
return -1;
}
case GNUTLS_CRD_SRP:
case GNUTLS_CRD_PSK:
case GNUTLS_CRD_ANON:
+ default:
/* This shouldn't occur. */
LOG(WARNING, "unexpected authentication method: %d", cred);
break;