/* Simple Osmocom System Monitor (osysmon): Support for OpenVPN monitoring */

/* (C) 2019 by sysmocom - s.f.m.c. GmbH.
 * Author: Max Suraev
 * All Rights Reserved.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *  This program 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.
 *
 *  This program 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 this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *  MA  02110-1301, USA.
 */

#include <string.h>
#include <stdbool.h>
#include <ctype.h>
#include <errno.h>

#include <osmocom/core/utils.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/command.h>
#include <osmocom/core/msgb.h>
#include <osmocom/netif/stream.h>

#include "osysmon.h"
#include "client.h"
#include "value_node.h"

/***********************************************************************
 * Data model
 ***********************************************************************/

#define OVPN_LOG(ctx, vpn, fmt, args...)				\
	fprintf(stderr, "OpenVPN [%s]: " fmt, make_authority(ctx, vpn->cfg), ##args)

/* max number of csv in response */
#define MAX_RESP_COMPONENTS 6

/* a single OpenVPN management interface client */
struct openvpn_client {
	/* links to osysmon.openvpn_clients */
	struct llist_head list;
	struct host_cfg *cfg;
	struct osmo_stream_cli *mgmt;
	/* fields below are parsed from response to 'state' command on mgmt interface */
	struct host_cfg *rem_cfg;
	char *tun_ip;
	bool connected;
};

/*
 * The string format is documented in https://openvpn.net/community-resources/management-interface/
 * Conversation loop looks like this (non-null terminated strings):
 * CLI -> SRV: "state"
 * SRV -> CLI: "1552674378,CONNECTED,SUCCESS,10.8.0.11,144.76.43.77,1194,," {0x0d, 0xa} "END" {0x0d, 0xa}
 * More or less comma-separated fields are returned depending on OpenVPN version.
 * v2.1.3: Sends only up to field 4 incl, eg: "1552674378,CONNECTED,SUCCESS,10.8.0.11,144.76.43.77" {0x0d, 0xa} "END" {0x0d, 0xa}
 */
static char *parse_state(struct msgb *msg, struct openvpn_client *vpn)
{
	char tmp[128], buf[128];
	char *tok;
	unsigned int i;
	uint8_t *m = msgb_data(msg);
	unsigned int truncated_len = OSMO_MIN(sizeof(tmp) - 1, msgb_length(msg));

	if (msgb_length(msg) > truncated_len)
		OVPN_LOG(msg, vpn, "received message too long (%d >= %u), truncating...\n", msgb_length(msg), truncated_len);

	if (msgb_length(msg) > 0) {
		if (!isdigit(m[0])) /* skip OpenVPN greetings and alike */
			return NULL;
	} else {
		OVPN_LOG(msg, vpn, "received message is empty, ignoring...\n");
		return NULL;
	}

	memcpy(tmp, m, truncated_len);
	tmp[truncated_len] = '\0';

	/* Only interested in first line; Remove return carriage, line feed + new line string "END" */
	for (i = 0; i < truncated_len; i++) {
		if (!isprint(tmp[i])) {
			tmp[i] = '\0';
			break;
		}
	}

	for (tok = strtok(tmp, ","), i = 0; tok && i < MAX_RESP_COMPONENTS; tok = strtok(NULL, ",")) {
		if (tok) { /* Parse csv string and pick interesting tokens while ignoring the rest. */
			switch (i++) {
			/* case 0: unix/date time, not needed */
			case 1:
				update_name(vpn->rem_cfg, tok);
				break;
			case 2:
				snprintf(buf, sizeof(buf), "%s (%s)", vpn->rem_cfg->name, tok);
				update_name(vpn->rem_cfg, buf);
			case 3:
				osmo_talloc_replace_string(vpn->rem_cfg, &vpn->tun_ip, tok);
				break;
			case 4:
				update_host(vpn->rem_cfg, tok);
				break;
			case 5:
				vpn->rem_cfg->remote_port = atoi(tok);
				break;
			}
		}
	}
	return NULL;
}

static struct openvpn_client *openvpn_client_find_or_make(const struct osysmon_state *os,
							  const char *host, uint16_t port)
{
	struct openvpn_client *vpn;
	llist_for_each_entry(vpn, &os->openvpn_clients, list) {
		if (match_config(vpn->cfg, host, MATCH_HOST) && vpn->cfg->remote_port == port)
			return vpn;
	}

	return NULL;
}

static int disconnect_cb(struct osmo_stream_cli *conn)
{
	struct openvpn_client *vpn = osmo_stream_cli_get_data(conn);

	update_name(vpn->rem_cfg, "disconnected from openvpn management socket");
	vpn->connected = false;
	talloc_free(vpn->tun_ip);
	talloc_free(vpn->rem_cfg->remote_host);
	vpn->tun_ip = NULL;
	vpn->rem_cfg->remote_host = NULL;

	return 0;
}

static int connect_cb(struct osmo_stream_cli *conn)
{
	struct openvpn_client *vpn = osmo_stream_cli_get_data(conn);

	update_name(vpn->rem_cfg, "connected to openvpn management socket");
	vpn->connected = true;

	return 0;
}

static int read_cb(struct osmo_stream_cli *conn)
{
	int bytes;
	struct openvpn_client *vpn = osmo_stream_cli_get_data(conn);
	struct msgb *msg = msgb_alloc(1024, "OpenVPN");
	if (!msg) {
		OVPN_LOG(conn, vpn, "unable to allocate message in callback\n");
		return 0;
	}

	bytes = osmo_stream_cli_recv(conn, msg);
	if (bytes < 0)
		OVPN_LOG(msg, vpn, "read on openvpn management socket failed (%d)\n", bytes);
	else
		parse_state(msg, vpn);

	msgb_free(msg);

	return 0;
}

static bool openvpn_client_create(struct osysmon_state *os, const char *name, const char *host, uint16_t port)
{
	struct openvpn_client *vpn = openvpn_client_find_or_make(os, host, port);
	if (vpn)
		return true;

	vpn = talloc_zero(os, struct openvpn_client);
	if (!vpn)
		return false;

	vpn->connected = false;

	vpn->cfg = host_cfg_alloc(vpn, name, host, port);
	if (!vpn->cfg)
		goto dealloc;

	vpn->rem_cfg = host_cfg_alloc(vpn, "connecting to openvpn management socket", NULL, 0);
	if (!vpn->rem_cfg)
		goto dealloc;

	vpn->mgmt = make_tcp_client(vpn->cfg);
	if (!vpn->mgmt)	{
		OVPN_LOG(vpn->rem_cfg, vpn, "failed to create TCP client\n");
		goto dealloc;
	}

	/* Wait for 1 minute before attempting to reconnect to management interface */
	osmo_stream_cli_set_reconnect_timeout(vpn->mgmt, 5);
	osmo_stream_cli_set_read_cb(vpn->mgmt, read_cb);
	osmo_stream_cli_set_connect_cb(vpn->mgmt, connect_cb);
	osmo_stream_cli_set_disconnect_cb(vpn->mgmt, disconnect_cb);

	if (osmo_stream_cli_open(vpn->mgmt) < 0) {
		OVPN_LOG(vpn->rem_cfg, vpn, "failed to connect to management socket\n");
		goto dealloc;
	}

	osmo_stream_cli_set_data(vpn->mgmt, vpn);
	llist_add_tail(&vpn->list, &os->openvpn_clients);

	return true;

dealloc:
	talloc_free(vpn);
	return false;
}

static void openvpn_client_destroy(struct openvpn_client *vpn)
{
	if (!vpn)
		return;

	osmo_stream_cli_destroy(vpn->mgmt);
	llist_del(&vpn->list);
	talloc_free(vpn);
}


/***********************************************************************
 * VTY
 ***********************************************************************/

#define OPENVPN_STR "Configure OpenVPN management interface address\n"

DEFUN(cfg_openvpn, cfg_openvpn_cmd,
      "openvpn HOST <1-65535>",
      OPENVPN_STR "Name of the host to connect to\n" "Management interface port\n")
{
	uint16_t port = atoi(argv[1]);

	if (!openvpn_client_create(g_oss, "OpenVPN", argv[0], port)) {
		vty_out(vty, "Failed to create OpenVPN client for %s:%u%s", argv[0], port, VTY_NEWLINE);
		return CMD_WARNING;
	}

	return CMD_SUCCESS;
}

DEFUN(cfg_no_openvpn, cfg_no_openvpn_cmd,
      "no openvpn HOST <1-65535>",
      NO_STR OPENVPN_STR "Name of the host to connect to\n" "Management interface port\n")
{
	uint16_t port = atoi(argv[1]);
	struct openvpn_client *vpn = openvpn_client_find_or_make(g_oss, argv[0], port);
	if (!vpn) {
		vty_out(vty, "OpenVPN client %s:%u doesn't exist%s", argv[0], port, VTY_NEWLINE);
		return CMD_WARNING;
	}

	openvpn_client_destroy(vpn);

	return CMD_SUCCESS;
}


/***********************************************************************
 * Runtime Code
 ***********************************************************************/

static int openvpn_client_poll(struct openvpn_client *vpn, struct value_node *parent)
{
	char *remote = make_authority(parent, vpn->rem_cfg);
	struct value_node *vn_host = value_node_find_or_add(parent, make_authority(parent, vpn->cfg));
	struct msgb *msg = msgb_alloc(128, "state");
	if (!msg) {
		value_node_add(vn_host, "msgb", "memory allocation failure");
		return 0;
	}

	if (vpn->rem_cfg->name)
		value_node_add(vn_host, "status", vpn->rem_cfg->name);

	if (vpn->tun_ip)
		value_node_add(vn_host, "tunnel", vpn->tun_ip);

	if (remote)
		value_node_add(vn_host, "remote", remote);

	if (vpn->connected) { /* re-trigger state command */
		msgb_printf(msg, "state\n");
		osmo_stream_cli_send(vpn->mgmt, msg);
	}

	return 0;
}

/* called once on startup before config file parsing */
int osysmon_openvpn_init()
{
	install_element(CONFIG_NODE, &cfg_openvpn_cmd);
	install_element(CONFIG_NODE, &cfg_no_openvpn_cmd);

	return 0;
}

/* called periodically */
int osysmon_openvpn_poll(struct value_node *parent)
{
	int num_vpns = llist_count(&g_oss->openvpn_clients);
	if (num_vpns) {
		struct value_node *vn_vpn = value_node_add(parent, "OpenVPN", NULL);
		struct openvpn_client *vpn;
		llist_for_each_entry(vpn, &g_oss->openvpn_clients, list)
			openvpn_client_poll(vpn, vn_vpn);
	}

	return num_vpns;
}
