/*
 * Access filtering
 */
/*
 * (C) 2010-2015 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2010-2012 by On-Waves
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <openbsc/bsc_msg_filter.h>

#include <openbsc/bsc_nat.h>
#include <openbsc/bsc_nat_sccp.h>
#include <openbsc/bsc_msc.h>
#include <openbsc/gsm_data.h>
#include <openbsc/debug.h>
#include <openbsc/ipaccess.h>

#include <osmocom/core/talloc.h>
#include <osmocom/gsm/gsm0808.h>

#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/protocol/gsm_04_11.h>

#include <osmocom/sccp/sccp.h>

struct filter_request {
	struct rb_root *black_list;
	struct llist_head *access_lists;
	const char *local_lst_name;
	const char *global_lst_name;
	int bsc_nr;
};

int bsc_filter_barr_find(struct rb_root *root, const char *imsi, int *cm, int *lu)
{
	struct bsc_filter_barr_entry *n;
	n = rb_entry(root->rb_node, struct bsc_filter_barr_entry, node);

	while (n) {
		int rc = strcmp(imsi, n->imsi);
		if (rc == 0) {
			*cm = n->cm_reject_cause;
			*lu = n->lu_reject_cause;
			return 1;
		}

		n = rb_entry(
			(rc < 0) ? n->node.rb_left : n->node.rb_right,
			struct bsc_filter_barr_entry, node);
	};

	return 0;
}

static int insert_barr_node(struct bsc_filter_barr_entry *entry, struct rb_root *root)
{
	struct rb_node **new = &root->rb_node, *parent = NULL;

	while (*new) {
		int rc;
		struct bsc_filter_barr_entry *this;
		this = rb_entry(*new, struct bsc_filter_barr_entry, node);
		parent = *new;

		rc = strcmp(entry->imsi, this->imsi);
		if (rc < 0)
			new = &((*new)->rb_left);
		else if (rc > 0)
			new = &((*new)->rb_right);
		else {
			LOGP(DNAT, LOGL_ERROR,
				"Duplicate entry for IMSI(%s)\n", entry->imsi);
			talloc_free(entry);
			return -1;
		}
	}

	rb_link_node(&entry->node, parent, new);
	rb_insert_color(&entry->node, root);
	return 0;
}

int bsc_filter_barr_adapt(void *ctx, struct rb_root *root,
			const struct osmo_config_list *list)
{
	struct osmo_config_entry *cfg_entry;
	int err = 0;

	/* free the old data */
	while (!RB_EMPTY_ROOT(root)) {
		struct rb_node *node = rb_first(root);
		rb_erase(node, root);
		talloc_free(node);
	}

	if (!list)
		return 0;

	/* now adapt the new list */
	llist_for_each_entry(cfg_entry, &list->entry, list) {
		struct bsc_filter_barr_entry *entry;
		entry = talloc_zero(ctx, struct bsc_filter_barr_entry);
		if (!entry) {
			LOGP(DNAT, LOGL_ERROR,
				"Allocation of the barr entry failed.\n");
			continue;
		}

		entry->imsi = talloc_strdup(entry, cfg_entry->mcc);
		entry->cm_reject_cause = atoi(cfg_entry->mnc);
		entry->lu_reject_cause = atoi(cfg_entry->option);
		err |= insert_barr_node(entry, root);
	}

	return err;
}


static int lst_check_deny(struct bsc_msg_acc_lst *lst, const char *mi_string,
			int *cm_cause, int *lu_cause)
{
	struct bsc_msg_acc_lst_entry *entry;

	llist_for_each_entry(entry, &lst->fltr_list, list) {
		if (!entry->imsi_deny)
			continue;
		if (regexec(&entry->imsi_deny_re, mi_string, 0, NULL, 0) == 0) {
			*cm_cause = entry->cm_reject_cause;
			*lu_cause = entry->lu_reject_cause;
			return 0;
		}
	}

	return 1;
}

/* apply white/black list */
static int auth_imsi(struct filter_request *req,
		const char *imsi,
		struct bsc_filter_reject_cause *cause)
{
	/*
	 * Now apply blacklist/whitelist of the BSC and the NAT.
	 * 1.) Check the global IMSI barr list
	 * 2.) Allow directly if the IMSI is allowed at the BSC
	 * 3.) Reject if the IMSI is not allowed at the BSC
	 * 4.) Reject if the IMSI not allowed at the global level.
	 * 5.) Allow directly if the IMSI is allowed at the global level
	 */
	int cm, lu;
	struct bsc_msg_acc_lst *nat_lst = NULL;
	struct bsc_msg_acc_lst *bsc_lst = NULL;

	/* 1. global check for barred imsis */
	if (bsc_filter_barr_find(req->black_list, imsi, &cm, &lu)) {
		cause->cm_reject_cause = cm;
		cause->lu_reject_cause = lu;
		LOGP(DNAT, LOGL_DEBUG,
			"Blocking subscriber IMSI %s with CM: %d LU: %d\n",
			imsi, cm, lu);
		return -4;
	}


	bsc_lst = bsc_msg_acc_lst_find(req->access_lists, req->local_lst_name);
	nat_lst = bsc_msg_acc_lst_find(req->access_lists, req->global_lst_name);


	if (bsc_lst) {
		/* 2. BSC allow */
		if (bsc_msg_acc_lst_check_allow(bsc_lst, imsi) == 0)
			return 1;

		/* 3. BSC deny */
		if (lst_check_deny(bsc_lst, imsi, &cm, &lu) == 0) {
			LOGP(DNAT, LOGL_ERROR,
			     "Filtering %s by imsi_deny on config nr: %d.\n", imsi, req->bsc_nr);
			rate_ctr_inc(&bsc_lst->stats->ctr[ACC_LIST_LOCAL_FILTER]);
			cause->cm_reject_cause = cm;
			cause->lu_reject_cause = lu;
			return -2;
		}

	}

	/* 4. NAT deny */
	if (nat_lst) {
		if (lst_check_deny(nat_lst, imsi, &cm, &lu) == 0) {
			LOGP(DNAT, LOGL_ERROR,
			     "Filtering %s global imsi_deny on bsc nr: %d.\n", imsi, req->bsc_nr);
			rate_ctr_inc(&nat_lst->stats->ctr[ACC_LIST_GLOBAL_FILTER]);
			cause->cm_reject_cause = cm;
			cause->lu_reject_cause = lu;
			return -3;
		}
	}

	return 1;
}

static int _cr_check_loc_upd(struct bsc_connection *bsc,
			     uint8_t *data, unsigned int length,
			     char **imsi)
{
	uint8_t mi_type;
	struct gsm48_loc_upd_req *lu;
	char mi_string[GSM48_MI_SIZE];

	if (length < sizeof(*lu)) {
		LOGP(DNAT, LOGL_ERROR,
		     "LU does not fit. Length is %d \n", length);
		return -1;
	}

	lu = (struct gsm48_loc_upd_req *) data;
	mi_type = lu->mi[0] & GSM_MI_TYPE_MASK;

	/*
	 * We can only deal with the IMSI. This will fail for a phone that
	 * will send the TMSI of a previous network to us.
	 */
	if (mi_type != GSM_MI_TYPE_IMSI)
		return 0;

	gsm48_mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len);
	*imsi = talloc_strdup(bsc, mi_string);
	return 1;
}

static int _cr_check_cm_serv_req(struct bsc_connection *bsc,
				 uint8_t *data, unsigned int length,
				 int *con_type, char **imsi)
{
	static const uint32_t classmark_offset =
				offsetof(struct gsm48_service_request, classmark);

	char mi_string[GSM48_MI_SIZE];
	uint8_t mi_type;
	int rc;
	struct gsm48_service_request *req;

	/* unfortunately in Phase1 the classmark2 length is variable */

	if (length < sizeof(*req)) {
		LOGP(DNAT, LOGL_ERROR,
		     "CM Serv Req does not fit. Length is %d\n", length);
		return -1;
	}

	req = (struct gsm48_service_request *) data;
	if (req->cm_service_type == 0x8)
		*con_type = NAT_CON_TYPE_SSA;
	rc = gsm48_extract_mi((uint8_t *) &req->classmark,
			      length - classmark_offset, mi_string, &mi_type);
	if (rc < 0) {
		LOGP(DNAT, LOGL_ERROR, "Failed to parse the classmark2/mi. error: %d\n", rc);
		return -1;
	}

	/* we have to let the TMSI or such pass */
	if (mi_type != GSM_MI_TYPE_IMSI)
		return 0;

	*imsi = talloc_strdup(bsc, mi_string);
	return 1;
}

static int _cr_check_pag_resp(struct bsc_connection *bsc,
			      uint8_t *data, unsigned int length, char **imsi)
{
	struct gsm48_pag_resp *resp;
	char mi_string[GSM48_MI_SIZE];
	uint8_t mi_type;

	if (length < sizeof(*resp)) {
		LOGP(DNAT, LOGL_ERROR, "PAG RESP does not fit. Length was %d.\n", length);
		return -1;
	}

	resp = (struct gsm48_pag_resp *) data;
	if (gsm48_paging_extract_mi(resp, length, mi_string, &mi_type) < 0) {
		LOGP(DNAT, LOGL_ERROR, "Failed to extract the MI.\n");
		return -1;
	}

	/* we need to let it pass for now */
	if (mi_type != GSM_MI_TYPE_IMSI)
		return 0;

	*imsi = talloc_strdup(bsc, mi_string);
	return 1;
}

static int _dt_check_id_resp(struct filter_request *req,
			     uint8_t *data, unsigned int length,
			     struct nat_sccp_connection *con,
			     struct bsc_filter_reject_cause *cause)
{
	char mi_string[GSM48_MI_SIZE];
	uint8_t mi_type;

	if (length < 2) {
		LOGP(DNAT, LOGL_ERROR, "mi does not fit.\n");
		return -1;
	}

	if (data[0] < length - 1) {
		LOGP(DNAT, LOGL_ERROR, "mi length too big.\n");
		return -2;
	}

	mi_type = data[1] & GSM_MI_TYPE_MASK;
	gsm48_mi_to_string(mi_string, sizeof(mi_string), &data[1], data[0]);

	if (mi_type != GSM_MI_TYPE_IMSI)
		return 0;

	con->imsi_checked = 1;
	con->imsi = talloc_strdup(con, mi_string);
	return auth_imsi(req, mi_string, cause);
}


/* Filter out CR data... */
int bsc_msg_filter_initial(struct gsm48_hdr *hdr48, size_t hdr48_len,
			struct bsc_connection *bsc,
			int *con_type,
			char **imsi, struct bsc_filter_reject_cause *cause)
{
	struct filter_request req;
	int ret = 0;
	uint8_t msg_type, proto;

	*con_type = NAT_CON_TYPE_NONE;
	cause->cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED;
	cause->lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED;
	*imsi = NULL;

	proto = hdr48->proto_discr & 0x0f;
	msg_type = hdr48->msg_type & 0xbf;
	if (proto == GSM48_PDISC_MM &&
	    msg_type == GSM48_MT_MM_LOC_UPD_REQUEST) {
		*con_type = NAT_CON_TYPE_LU;
		ret = _cr_check_loc_upd(bsc, &hdr48->data[0],
					hdr48_len - sizeof(*hdr48), imsi);
	} else if (proto == GSM48_PDISC_MM &&
		  msg_type == GSM48_MT_MM_CM_SERV_REQ) {
		*con_type = NAT_CON_TYPE_CM_SERV_REQ;
		ret = _cr_check_cm_serv_req(bsc, &hdr48->data[0],
					     hdr48_len - sizeof(*hdr48),
					     con_type, imsi);
	} else if (proto == GSM48_PDISC_RR &&
		   msg_type == GSM48_MT_RR_PAG_RESP) {
		*con_type = NAT_CON_TYPE_PAG_RESP;
		ret = _cr_check_pag_resp(bsc, &hdr48->data[0],
					hdr48_len - sizeof(*hdr48), imsi);
	} else {
		/* We only want to filter the above, let other things pass */
		*con_type = NAT_CON_TYPE_OTHER;
		return 0;
	}

	/* check if we are done */
	if (ret != 1)
		return ret;

	/* the memory allocation failed */
	if (!*imsi)
		return -1;

	/* now check the imsi */
	req.black_list = &bsc->nat->imsi_black_list;
	req.access_lists = &bsc->nat->access_lists;
	req.local_lst_name = bsc->cfg->acc_lst_name;
	req.global_lst_name = bsc->nat->acc_lst_name;
	req.bsc_nr = bsc->cfg->nr;
	return auth_imsi(&req, *imsi, cause);
}

int bsc_msg_filter_data(struct gsm48_hdr *hdr48, size_t len,
		struct bsc_connection *bsc,
		struct nat_sccp_connection *con,
		struct bsc_filter_reject_cause *cause)
{
	struct filter_request req;
	uint8_t msg_type, proto;

	cause->cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED;
	cause->lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED;

	if (con->imsi_checked)
		return 0;

	proto = hdr48->proto_discr & 0x0f;
	msg_type = hdr48->msg_type & 0xbf;
	if (proto != GSM48_PDISC_MM || msg_type != GSM48_MT_MM_ID_RESP)
		return 0;

	req.black_list = &bsc->nat->imsi_black_list;
	req.access_lists = &bsc->nat->access_lists;
	req.local_lst_name = bsc->cfg->acc_lst_name;
	req.global_lst_name = bsc->nat->acc_lst_name;
	req.bsc_nr = bsc->cfg->nr;
	return _dt_check_id_resp(&req, &hdr48->data[0],
					len - sizeof(*hdr48), con, cause);
}
