odyssey/sources/tls.c

241 lines
5.9 KiB
C
Raw Normal View History

/*
2017-07-05 12:42:49 +00:00
* Odissey.
*
2017-07-05 12:42:49 +00:00
* Advanced PostgreSQL connection pooler.
*/
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <signal.h>
#include <machinarium.h>
2017-06-07 11:50:58 +00:00
#include <shapito.h>
#include "sources/macro.h"
#include "sources/version.h"
2017-08-08 13:50:50 +00:00
#include "sources/atomic.h"
#include "sources/list.h"
#include "sources/pid.h"
#include "sources/id.h"
2017-07-26 14:05:29 +00:00
#include "sources/log_file.h"
#include "sources/log_system.h"
#include "sources/logger.h"
#include "sources/daemon.h"
#include "sources/scheme.h"
#include "sources/scheme_mgr.h"
#include "sources/config.h"
#include "sources/msg.h"
#include "sources/system.h"
#include "sources/instance.h"
#include "sources/server.h"
#include "sources/server_pool.h"
#include "sources/client.h"
#include "sources/client_pool.h"
#include "sources/route_id.h"
#include "sources/route.h"
#include "sources/route_pool.h"
#include "sources/io.h"
#include "sources/router.h"
#include "sources/pooler.h"
#include "sources/relay.h"
#include "sources/tls.h"
#include "sources/frontend.h"
2017-06-13 11:57:54 +00:00
machine_tls_t*
od_tls_frontend(od_schemelisten_t *scheme)
{
int rc;
2017-06-13 11:57:54 +00:00
machine_tls_t *tls;
tls = machine_tls_create();
if (tls == NULL)
return NULL;
2017-07-28 13:19:53 +00:00
if (scheme->tls_mode == OD_TLS_ALLOW)
machine_tls_set_verify(tls, "none");
else
2017-07-28 13:19:53 +00:00
if (scheme->tls_mode == OD_TLS_REQUIRE)
machine_tls_set_verify(tls, "peer");
else
machine_tls_set_verify(tls, "peer_strict");
if (scheme->tls_ca_file) {
rc = machine_tls_set_ca_file(tls, scheme->tls_ca_file);
if (rc == -1) {
machine_tls_free(tls);
return NULL;
}
}
if (scheme->tls_cert_file) {
rc = machine_tls_set_cert_file(tls, scheme->tls_cert_file);
if (rc == -1) {
machine_tls_free(tls);
return NULL;
}
}
if (scheme->tls_key_file) {
rc = machine_tls_set_key_file(tls, scheme->tls_key_file);
if (rc == -1) {
machine_tls_free(tls);
return NULL;
}
}
return tls;
}
int
od_tls_frontend_accept(od_client_t *client,
2017-07-26 14:05:29 +00:00
od_logger_t *logger,
od_schemelisten_t *scheme,
2017-06-13 11:57:54 +00:00
machine_tls_t *tls)
{
2017-07-06 13:36:14 +00:00
shapito_stream_t *stream = &client->stream;
if (client->startup.is_ssl_request)
{
2017-07-26 14:05:29 +00:00
od_debug_client(logger, &client->id, "tls", "ssl request");
2017-07-06 13:36:14 +00:00
shapito_stream_reset(stream);
int rc;
2017-07-28 13:19:53 +00:00
if (scheme->tls_mode == OD_TLS_DISABLE) {
/* not supported 'N' */
2017-07-06 13:36:14 +00:00
shapito_stream_write8(stream, 'N');
rc = od_write(client->io, stream);
if (rc == -1) {
2017-07-26 14:05:29 +00:00
od_error_client(logger, &client->id, "tls", "write error: %s",
machine_error(client->io));
return -1;
}
2017-07-26 14:05:29 +00:00
od_log_client(logger, &client->id, "tls", "disabled, closing");
2017-07-06 13:36:14 +00:00
od_frontend_error(client, SHAPITO_FEATURE_NOT_SUPPORTED,
2017-06-08 12:36:21 +00:00
"SSL is not supported");
return -1;
}
/* supported 'S' */
2017-07-06 13:36:14 +00:00
shapito_stream_write8(stream, 'S');
rc = od_write(client->io, stream);
if (rc == -1) {
2017-07-26 14:05:29 +00:00
od_error_client(logger, &client->id, "tls", "write error: %s",
machine_error(client->io));
return -1;
}
rc = machine_set_tls(client->io, tls);
if (rc == -1) {
2017-07-26 14:05:29 +00:00
od_error_client(logger, &client->id, "tls", "error: %s",
machine_error(client->io));
return -1;
}
2017-07-26 14:05:29 +00:00
od_debug_client(logger, &client->id, "tls", "ok");
return 0;
}
2017-07-28 13:19:53 +00:00
switch (scheme->tls_mode) {
case OD_TLS_DISABLE:
case OD_TLS_ALLOW:
break;
default:
2017-07-26 14:05:29 +00:00
od_log_client(logger, &client->id, "tls", "required, closing");
2017-07-06 13:36:14 +00:00
od_frontend_error(client, SHAPITO_PROTOCOL_VIOLATION,
2017-06-08 12:36:21 +00:00
"SSL is required");
return -1;
}
return 0;
}
2017-06-13 11:57:54 +00:00
machine_tls_t*
od_tls_backend(od_schemestorage_t *scheme)
{
int rc;
2017-06-13 11:57:54 +00:00
machine_tls_t *tls;
tls = machine_tls_create();
if (tls == NULL)
return NULL;
2017-07-28 13:19:53 +00:00
if (scheme->tls_mode == OD_TLS_ALLOW)
machine_tls_set_verify(tls, "none");
else
2017-07-28 13:19:53 +00:00
if (scheme->tls_mode == OD_TLS_REQUIRE)
machine_tls_set_verify(tls, "peer");
else
machine_tls_set_verify(tls, "peer_strict");
if (scheme->tls_ca_file) {
rc = machine_tls_set_ca_file(tls, scheme->tls_ca_file);
if (rc == -1) {
machine_tls_free(tls);
return NULL;
}
}
if (scheme->tls_cert_file) {
rc = machine_tls_set_cert_file(tls, scheme->tls_cert_file);
if (rc == -1) {
machine_tls_free(tls);
return NULL;
}
}
if (scheme->tls_key_file) {
rc = machine_tls_set_key_file(tls, scheme->tls_key_file);
if (rc == -1) {
machine_tls_free(tls);
return NULL;
}
}
return tls;
}
int
od_tls_backend_connect(od_server_t *server,
2017-07-26 14:05:29 +00:00
od_logger_t *logger,
od_schemestorage_t *scheme)
{
2017-07-06 13:36:14 +00:00
shapito_stream_t *stream = &server->stream;
2017-07-26 14:05:29 +00:00
od_debug_server(logger, &server->id, "tls", "init");
/* SSL Request */
2017-07-06 13:36:14 +00:00
shapito_stream_reset(stream);
int rc;
2017-07-06 13:36:14 +00:00
rc = shapito_fe_write_ssl_request(stream);
if (rc == -1)
return -1;
rc = od_write(server->io, stream);
if (rc == -1) {
2017-07-26 14:05:29 +00:00
od_error_server(logger, &server->id, "tls", "write error: %s",
machine_error(server->io));
return -1;
}
/* read server reply */
2017-07-06 13:36:14 +00:00
shapito_stream_reset(stream);
rc = machine_read(server->io, stream->pos, 1, UINT32_MAX);
2017-06-14 12:35:04 +00:00
if (rc == -1) {
2017-07-26 14:05:29 +00:00
od_error_server(logger, &server->id, "tls", "read error: %s",
machine_error(server->io));
return -1;
}
switch (*stream->pos) {
case 'S':
/* supported */
2017-07-26 14:05:29 +00:00
od_debug_server(logger, &server->id, "tls", "supported");
rc = machine_set_tls(server->io, server->tls);
if (rc == -1) {
2017-07-26 14:05:29 +00:00
od_error_server(logger, &server->id, "tls", "error: %s",
machine_error(server->io));
return -1;
}
2017-07-26 14:05:29 +00:00
od_debug_server(logger, &server->id, "tls", "ok");
break;
case 'N':
/* not supported */
2017-07-28 13:19:53 +00:00
if (scheme->tls_mode == OD_TLS_ALLOW) {
2017-07-26 14:05:29 +00:00
od_debug_server(logger, &server->id, "tls", "not supported, continue (allow)");
} else {
2017-07-26 14:05:29 +00:00
od_error_server(logger, &server->id, "tls", "not supported, closing");
return -1;
}
break;
default:
2017-07-26 14:05:29 +00:00
od_error_server(logger, &server->id, "tls", "unexpected status reply");
return -1;
}
return 0;
}