/*****************************************************************************\
 *  certmgr.c - certmgr API definitions
 *****************************************************************************
 *  Copyright (C) SchedMD LLC.
 *
 *  This file is part of Slurm, a resource management program.
 *  For details, see <https://slurm.schedmd.com/>.
 *  Please also read the included file: DISCLAIMER.
 *
 *  Slurm is free software; you can redistribute it and/or modify it under
 *  the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of portions of this program with the OpenSSL library under
 *  certain conditions as described in each individual source file, and
 *  distribute linked combinations including the two. You must obey the GNU
 *  General Public License in all respects for all of the code used other than
 *  OpenSSL. If you modify file(s) with this exception, you may extend this
 *  exception to your version of the file(s), but you are not obligated to do
 *  so. If you do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source files in
 *  the program, then also delete it here.
 *
 *  Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with Slurm; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
\*****************************************************************************/

#include "src/common/macros.h"
#include "src/common/parse_time.h"
#include "src/common/plugin.h"
#include "src/common/plugrack.h"
#include "src/common/read_config.h"
#include "src/common/slurm_protocol_api.h"
#include "src/common/state_save.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"
#include "src/conmgr/conmgr.h"

#include "src/interfaces/certmgr.h"
#include "src/interfaces/conn.h"

typedef struct {
	char *(*get_node_cert_key)(char *node_name);
	char *(*get_node_token)(char *node_name);
	char *(*generate_csr)(char *node_name);
	char *(*sign_csr)(char *csr, bool is_client_auth, char *token,
			  char *name);
} certmgr_ops_t;

/*
 * These strings must be kept in the same order as the fields
 * declared for certmgr_ops_t.
 */
static const char *syms[] = {
	"certmgr_p_get_node_cert_key",
	"certmgr_p_get_node_token",
	"certmgr_p_generate_csr",
	"certmgr_p_sign_csr",
};

static certmgr_ops_t ops;
static plugin_context_t *g_context = NULL;
static plugin_init_t plugin_inited = PLUGIN_NOT_INITED;
static pthread_rwlock_t context_lock = PTHREAD_RWLOCK_INITIALIZER;

static char *conf_spooldir = NULL;

extern bool certmgr_enabled(void)
{
	return (plugin_inited == PLUGIN_INITED);
}

extern int certmgr_get_renewal_period_mins(void)
{
	static int renewal_period = -1;
	char *renewal_str = NULL;

	if (renewal_period > 0)
		return renewal_period;

	if ((renewal_str = conf_get_opt_str(slurm_conf.certmgr_params,
					    "certificate_renewal_period="))) {
		int i = atoi(renewal_str);
		if (i < 0) {
			error("Invalid certificate_renewal_period: %s. Needs to be positive integer",
			      renewal_str);
			xfree(renewal_str);
			return SLURM_ERROR;
		}

		renewal_period = i;
		xfree(renewal_str);
		return renewal_period;
	} else {
		/* default setting */
		renewal_period = DAY_MINUTES;
	}

	return renewal_period;
}

extern int certmgr_g_init(void)
{
	int rc = SLURM_SUCCESS;
	char *plugin_type = "certmgr";

	slurm_rwlock_wrlock(&context_lock);

	if (plugin_inited != PLUGIN_NOT_INITED)
		goto done;

	if (!slurm_conf.certmgr_type) {
		plugin_inited = PLUGIN_NOOP;
		goto done;
	}

	g_context = plugin_context_create(plugin_type, slurm_conf.certmgr_type,
					  (void **) &ops, syms, sizeof(syms));

	if (!g_context) {
		error("cannot create %s context for %s",
		      plugin_type, slurm_conf.certmgr_type);
		rc = SLURM_ERROR;
		plugin_inited = PLUGIN_NOT_INITED;
		goto done;
	}

	if (certmgr_get_renewal_period_mins() == SLURM_ERROR) {
		rc = SLURM_ERROR;
		plugin_inited = PLUGIN_NOT_INITED;
		goto done;
	}

	plugin_inited = PLUGIN_INITED;

done:
	slurm_rwlock_unlock(&context_lock);
	return rc;
}

extern int certmgr_g_fini(void)
{
	int rc = SLURM_SUCCESS;

	slurm_rwlock_wrlock(&context_lock);

	if (g_context) {
		rc = plugin_context_destroy(g_context);
		g_context = NULL;
	}

	plugin_inited = PLUGIN_NOT_INITED;

	slurm_rwlock_unlock(&context_lock);

	return rc;
}

extern char *certmgr_g_get_node_cert_key(char *node_name)
{
	xassert(running_in_slurmd() || running_in_sackd());
	xassert(plugin_inited != PLUGIN_NOT_INITED);

	if (plugin_inited == PLUGIN_NOOP)
		return SLURM_SUCCESS;

	return (*(ops.get_node_cert_key))(node_name);
}

extern char *certmgr_g_get_node_token(char *node_name)
{
	xassert(running_in_slurmd() || running_in_sackd());
	xassert(plugin_inited != PLUGIN_NOT_INITED);

	if (plugin_inited == PLUGIN_NOOP)
		return NULL;

	return (*(ops.get_node_token))(node_name);
}

extern char *certmgr_g_generate_csr(char *node_name)
{
	xassert(running_in_slurmd() || running_in_sackd());
	xassert(plugin_inited != PLUGIN_NOT_INITED);

	if (plugin_inited == PLUGIN_NOOP)
		return NULL;

	return (*(ops.generate_csr))(node_name);
}

extern char *certmgr_g_sign_csr(char *csr, bool is_client_auth, char *token,
				char *name)
{
	xassert(running_in_slurmctld());
	xassert(plugin_inited != PLUGIN_NOT_INITED);

	if (plugin_inited == PLUGIN_NOOP)
		return NULL;

	return (*(ops.sign_csr))(csr, is_client_auth, token, name);
}

static void _get_tls_cert_work(conmgr_callback_args_t conmgr_args, void *arg)
{
	char *name = arg;
	time_t delay_seconds;
	char time_str[256];

	xassert(name);

	if (conmgr_args.status != CONMGR_WORK_STATUS_RUN)
		return;

	if (certmgr_get_cert_from_ctld(name, false)) {
		/*
		 * Don't do full delay between tries to get TLS certificate if
		 * we failed to get it.
		 */
		delay_seconds = slurm_conf.msg_timeout;
		debug("Retry getting TLS certificate in %lu seconds...",
		      delay_seconds);
	} else {
		delay_seconds =
			certmgr_get_renewal_period_mins() * MINUTE_SECONDS;
	}

	/* Periodically renew TLS certificate indefinitely */
	conmgr_add_work_delayed_fifo(_get_tls_cert_work, name, delay_seconds,
				     0);

	if (slurm_conf.debug_flags & DEBUG_FLAG_AUDIT_TLS) {
		time_t next_renewal = time(NULL) + delay_seconds;
		slurm_make_time_str(&next_renewal, time_str, sizeof(time_str));
		log_flag(AUDIT_TLS, "Next certificate renewal will happen at %s",
			 time_str);
	}
}

static void _pack_cert_and_key(char *cert, char *key, time_t last_renewal,
			       buf_t *buffer)
{
	uint16_t version = SLURM_PROTOCOL_VERSION;

	pack16(version, buffer);

	pack_time(last_renewal, buffer);
	packstr(cert, buffer);
	packstr(key, buffer);
}

static int _unpack_cert_and_key(char **cert_ptr, char **key_ptr,
				time_t *last_renewal, buf_t *buffer)
{
	uint16_t version = 0;

	xassert(running_in_slurmd());

	safe_unpack16(&version, buffer);

	if (version >= SLURM_MIN_PROTOCOL_VERSION) {
		safe_unpack_time(last_renewal, buffer);
		safe_unpackstr(cert_ptr, buffer);
		safe_unpackstr(key_ptr, buffer);
	} else {
		error("certmgr_state has invalid protocol version %d", version);
		return SLURM_ERROR;
	}

	return SLURM_SUCCESS;

unpack_error:
	error("Unable to unpack certmgr_state");
	return SLURM_ERROR;
}

static int _get_cert_and_key_from_state(char **cert_ptr, char **key_ptr,
					time_t *last_renewal)
{
	int rc = SLURM_SUCCESS;
	char *state_file = NULL;
	char *tmp_state_file;
	buf_t *buffer = NULL;

	xstrfmtcat(state_file, "%s/certmgr_state", conf_spooldir);

	if (!(buffer = state_save_open(state_file, &tmp_state_file))) {
		rc = SLURM_ERROR;
		goto end;
	}

	if (_unpack_cert_and_key(cert_ptr, key_ptr, last_renewal, buffer)) {
		rc = SLURM_ERROR;
	}

end:
	xfree(tmp_state_file);
	xfree(state_file);
	FREE_NULL_BUFFER(buffer);
	return rc;
}

static int _load_cert_and_key_from_state(time_t now,
					 time_t renewal_period_seconds,
					 time_t *secs_since_last_renewal_ptr)
{
	char time_str[256];
	int rc = SLURM_SUCCESS;
	char *cert = NULL, *key = NULL;
	size_t cert_len, key_len;
	time_t last_renewal = 0, secs_since_last_renewal = 0;

	if (!conf_spooldir)
		return SLURM_ERROR;

	if (_get_cert_and_key_from_state(&cert, &key, &last_renewal)) {
		log_flag(AUDIT_TLS, "Could not find cert/key pair in state, getting new signed certificate from slurmctld now");
		return SLURM_ERROR;
	}

	cert_len = strlen(cert);
	key_len = strlen(key);

	/*
	 * Found cert/key in state, need to determine when to renew the
	 * certificate based on the last renewal time read from state. If the
	 * cert/key from state is too old, get a signed certificate from
	 * slurmctld now.
	 */
	secs_since_last_renewal = now - last_renewal;
	if (secs_since_last_renewal >= renewal_period_seconds) {
		slurm_make_time_str(&last_renewal, time_str, sizeof(time_str));
		log_flag(AUDIT_TLS,
			"More time than the renewal period of %d minute(s) has passed since the cert in state was renewed (%s). Renewing certificate now.",
			certmgr_get_renewal_period_mins(), time_str);
		rc = SLURM_ERROR;
		goto end;
	}

	if (slurm_conf.debug_flags & DEBUG_FLAG_AUDIT_TLS) {
		secs2time_str(secs_since_last_renewal, time_str,
			      sizeof(time_str));
		log_flag(AUDIT_TLS, "Certificate renewal delay is reduced by %s based on last renewal time read from state.",
			 time_str);
	}

	if (conn_g_load_own_cert(cert, cert_len, key, key_len)) {
		error("%s: Could not load signed certificate and private key from state",
		      __func__);
		rc = SLURM_ERROR;
		goto end;
	}

	log_flag(AUDIT_TLS, "Successfully loaded signed certificate and private key from state");
	*secs_since_last_renewal_ptr = secs_since_last_renewal;
end:
	xfree(cert);
	xfree(key);
	return rc;
}

static int _save_cert_and_key_to_state(char *cert, char *key)
{
	int rc = SLURM_SUCCESS;
	char *state_file = NULL;
	buf_t *buffer = init_buf(1024);

	_pack_cert_and_key(cert, key, time(NULL), buffer);

	xstrfmtcat(state_file, "%s/certmgr_state", conf_spooldir);
	if (save_buf_to_state(state_file, buffer, NULL) < 0) {
		error("Failed to write cert/key pair to %s", state_file);
		rc = SLURM_ERROR;
		goto end;
	}

	log_flag(AUDIT_TLS, "Successfully saved signed certificate and private key to state");
end:

	xfree(state_file);
	FREE_NULL_BUFFER(buffer);
	return rc;
}

extern void certmgr_client_daemon_init(char *name, char *spooldir)
{
	char time_str[256];
	char hostname[HOST_NAME_MAX];
	time_t delay_until_next_renewal = 0, secs_since_last_renewal = 0;
	time_t renewal_period_seconds = 0;
	time_t now = time(NULL);

	if (!name) {
		if (gethostname(hostname, HOST_NAME_MAX))
			fatal("Could not get hostname, cannot get TLS certificate from slurmctld.");
		name = hostname;
	}

	renewal_period_seconds =
		(certmgr_get_renewal_period_mins() * MINUTE_SECONDS);

	/* Get initial cert/key either from state or from slurmctld */
	conf_spooldir = spooldir;
	if (!_load_cert_and_key_from_state(now, renewal_period_seconds,
					   &secs_since_last_renewal)) {
		/*
		 * Got valid cert/key from state, don't get signed cert from
		 * slurmctld now, wait until next renewal.
		 */
	} else if (certmgr_get_cert_from_ctld(name, true)) {
		fatal("Unable to retrieve signed certificate from slurmctld due to misconfiguration.");
	}

	/*
	 * Setup indefinite certificate renewal after retrieving the
	 * an initial signed certificate.
	 */
	delay_until_next_renewal =
		renewal_period_seconds - secs_since_last_renewal;
	conmgr_add_work_delayed_fifo(_get_tls_cert_work, name,
				     delay_until_next_renewal, 0);

	if (slurm_conf.debug_flags & DEBUG_FLAG_AUDIT_TLS) {
		time_t next_renewal = now + delay_until_next_renewal;
		slurm_make_time_str(&next_renewal, time_str, sizeof(time_str));
		log_flag(AUDIT_TLS, "Next certificate renewal will happen at %s",
			 time_str);
	}
}

extern int certmgr_get_cert_from_ctld(char *name, bool retry_forever)
{
	slurm_msg_t req, resp;
	tls_cert_request_msg_t *cert_req;
	tls_cert_response_msg_t *cert_resp;
	size_t cert_len, key_len;
	char *key;

	slurm_msg_t_init(&req);
	slurm_msg_t_init(&resp);

	cert_req = xmalloc(sizeof(*cert_req));

	if (conn_g_own_cert_loaded()) {
		log_flag(AUDIT_TLS, "Using previously signed certificate to authenticate with slurmctld via mTLS");
	} else if (!(cert_req->token = certmgr_g_get_node_token(name))) {
		error("%s: Failed to get unique node token", __func__);
		slurm_free_tls_cert_request_msg(cert_req);
		return SLURM_ERROR;
	}

	if (!(cert_req->csr = certmgr_g_generate_csr(name))) {
		error("%s: Failed to generate certificate signing request",
		      __func__);
		slurm_free_tls_cert_request_msg(cert_req);
		return SLURM_ERROR;
	}

	cert_req->node_name = xstrdup(name);

	req.msg_type = REQUEST_TLS_CERT;
	req.data = cert_req;

	log_flag(AUDIT_TLS, "Sending certificate signing request to slurmctld:\n%s",
		 cert_req->csr);

retry:
	if (slurm_send_recv_controller_msg(&req, &resp, working_cluster_rec) <
	    0) {
		error("Unable to get TLS certificate from slurmctld: %m");
		if (retry_forever) {
			debug("Retry getting TLS certificate in %d seconds...",
			      slurm_conf.msg_timeout);
			sleep(slurm_conf.msg_timeout);
			goto retry;
		}
		slurm_free_tls_cert_request_msg(cert_req);
		return SLURM_ERROR;
	}
	slurm_free_tls_cert_request_msg(cert_req);

	switch (resp.msg_type) {
	case RESPONSE_TLS_CERT:
		break;
	case RESPONSE_SLURM_RC:
	{
		uint32_t resp_rc =
			((return_code_msg_t *) resp.data)->return_code;
		error("%s: slurmctld response to TLS certificate request: %s",
		      __func__, slurm_strerror(resp_rc));
		return SLURM_ERROR;
	}
	default:
		error("%s: slurmctld responded with unexpected msg type: %s",
		      __func__, rpc_num2string(resp.msg_type));
		return SLURM_ERROR;
	}

	cert_resp = resp.data;

	log_flag(AUDIT_TLS, "Successfully got signed certificate from slurmctld:\n%s",
		 cert_resp->signed_cert);

	if (!(key = certmgr_g_get_node_cert_key(name))) {
		error("%s: Could not get node's private key", __func__);
		return SLURM_ERROR;
	}

	cert_len = strlen(cert_resp->signed_cert);
	key_len = strlen(key);

	if (conn_g_load_own_cert(cert_resp->signed_cert, cert_len, key,
				 key_len)) {
		error("%s: Could not load signed certificate and private key into tls plugin",
		      __func__);
		return SLURM_ERROR;
	}

	if (running_in_slurmd() &&
	    _save_cert_and_key_to_state(cert_resp->signed_cert, key)) {
		error("%s: Failed to save signed certificate and key to state. A new signed certificate will need to be retrieved after restart",
		      __func__);
	}

	xfree(key);
	slurm_free_msg_data(RESPONSE_TLS_CERT, cert_resp);

	return SLURM_SUCCESS;
}
