Exemple #1
0
static void ussd_auth_con(struct tlv_parsed *tvp, struct bsc_nat_ussd_con *conn)
{
	const char *token;
	int len;
	if (!conn->nat->ussd_token) {
		LOGP(DNAT, LOGL_ERROR, "No USSD token set. Closing\n");
		bsc_nat_ussd_destroy(conn);
		return;
	}

	token = (const char *) TLVP_VAL(tvp, IPAC_IDTAG_UNITNAME);
 	len = TLVP_LEN(tvp, IPAC_IDTAG_UNITNAME);
	if (strncmp(conn->nat->ussd_token, token, len) != 0) {
		LOGP(DNAT, LOGL_ERROR, "Wrong USSD token by client: %d\n",
			conn->queue.bfd.fd);
		bsc_nat_ussd_destroy(conn);
		return;
	}

	/* it is authenticated now */
	if (conn->nat->ussd_con && conn->nat->ussd_con != conn)
		bsc_nat_ussd_destroy(conn->nat->ussd_con);

	LOGP(DNAT, LOGL_ERROR, "USSD token specified. USSD provider is connected.\n");
	osmo_timer_del(&conn->auth_timeout);
	conn->authorized = 1;
	conn->nat->ussd_con = conn;
}
Exemple #2
0
static void ussd_auth_con(struct tlv_parsed *tvp, struct bsc_nat_ussd_con *conn)
{
	const char *token;
	int len;
	if (!conn->nat->ussd_token) {
		LOGP(DNAT, LOGL_ERROR, "No USSD token set. Closing\n");
		bsc_nat_ussd_destroy(conn);
		return;
	}

	token = (const char *) TLVP_VAL(tvp, IPAC_IDTAG_UNITNAME);
 	len = TLVP_LEN(tvp, IPAC_IDTAG_UNITNAME);

	/* last byte should be a NULL */
	if (strlen(conn->nat->ussd_token) != len - 1)
		goto disconnect;
	/* compare everything including the null byte */
	if (memcmp(conn->nat->ussd_token, token, len) != 0)
		goto disconnect;

	/* it is authenticated now */
	if (conn->nat->ussd_con && conn->nat->ussd_con != conn)
		bsc_nat_ussd_destroy(conn->nat->ussd_con);

	LOGP(DNAT, LOGL_ERROR, "USSD token specified. USSD provider is connected.\n");
	osmo_timer_del(&conn->auth_timeout);
	conn->authorized = 1;
	conn->nat->ussd_con = conn;
	return;

disconnect:
	LOGP(DNAT, LOGL_ERROR, "Wrong USSD token by client: %d\n",
		conn->queue.bfd.fd);
	bsc_nat_ussd_destroy(conn);
}
Exemple #3
0
static int ussd_read_cb(struct osmo_fd *bfd)
{
	struct bsc_nat_ussd_con *conn = bfd->data;
	struct msgb *msg = NULL;
	struct ipaccess_head *hh;
	int ret;

	ret = ipa_msg_recv_buffered(bfd->fd, &msg, &conn->pending_msg);
	if (ret <= 0) {
		if (ret == -EAGAIN)
			return 0;
		LOGP(DNAT, LOGL_ERROR, "USSD Connection was lost.\n");
		bsc_nat_ussd_destroy(conn);
		return -1;
	}

	LOGP(DNAT, LOGL_NOTICE, "MSG from USSD: %s proto: %d\n",
		osmo_hexdump(msg->data, msg->len), msg->l2h[0]);
	hh = (struct ipaccess_head *) msg->data;

	if (hh->proto == IPAC_PROTO_IPACCESS) {
		if (msg->l2h[0] == IPAC_MSGT_ID_RESP) {
			struct tlv_parsed tvp;
			int ret;
			ret = ipa_ccm_idtag_parse(&tvp,
					     (unsigned char *) msg->l2h + 2,
					     msgb_l2len(msg) - 2);
			if (ret < 0) {
				LOGP(DNAT, LOGL_ERROR, "ignoring IPA response "
					"message with malformed TLVs\n");
				msgb_free(msg);
				return ret;
			}
			if (TLVP_PRESENT(&tvp, IPAC_IDTAG_UNITNAME))
				ussd_auth_con(&tvp, conn);
		} else if (msg->l2h[0] == IPAC_MSGT_PING) {
			LOGP(DNAT, LOGL_DEBUG, "Got USSD ping request.\n");
			ussd_pong(conn);
		} else {
			LOGP(DNAT, LOGL_NOTICE, "Got unknown IPACCESS message 0x%02x.\n", msg->l2h[0]);
		}

		msgb_free(msg);
	} else if (hh->proto == IPAC_PROTO_SCCP) {
		forward_sccp(conn->nat, msg);
	} else {
		msgb_free(msg);
	}

	return 0;
}
Exemple #4
0
static int ussd_listen_cb(struct osmo_fd *bfd, unsigned int what)
{
	struct bsc_nat_ussd_con *conn;
	struct bsc_nat *nat;
	struct sockaddr_in sa;
	socklen_t sa_len = sizeof(sa);
	int fd;

	if (!(what & BSC_FD_READ))
		return 0;

	fd = accept(bfd->fd, (struct sockaddr *) &sa, &sa_len);
	if (fd < 0) {
		perror("accept");
		return fd;
	}

	nat = (struct bsc_nat *) bfd->data;
	osmo_counter_inc(nat->stats.ussd.reconn);

	conn = bsc_nat_ussd_alloc(nat);
	if (!conn) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate USSD con struct.\n");
		close(fd);
		return -1;
	}

	osmo_wqueue_init(&conn->queue, 10);
	conn->queue.bfd.data = conn;
	conn->queue.bfd.fd = fd;
	conn->queue.bfd.when = BSC_FD_READ;
	conn->queue.read_cb = ussd_read_cb;
	conn->queue.write_cb = bsc_write_cb;

	if (osmo_fd_register(&conn->queue.bfd) < 0) {
		LOGP(DNAT, LOGL_ERROR, "Failed to register USSD fd.\n");
		bsc_nat_ussd_destroy(conn);
		return -1;
	}

	LOGP(DNAT, LOGL_NOTICE, "USSD Connection on %d with IP: %s\n",
	     fd, inet_ntoa(sa.sin_addr));

	/* do authentication */
	ussd_start_auth(conn);
	return 0;
}
Exemple #5
0
static int ussd_read_cb(struct osmo_fd *bfd)
{
	int error;
	struct bsc_nat_ussd_con *conn = bfd->data;
	struct msgb *msg = ipaccess_read_msg(bfd, &error);
	struct ipaccess_head *hh;

	if (!msg) {
		LOGP(DNAT, LOGL_ERROR, "USSD Connection was lost.\n");
		bsc_nat_ussd_destroy(conn);
		return -1;
	}

	LOGP(DNAT, LOGL_NOTICE, "MSG from USSD: %s proto: %d\n",
		osmo_hexdump(msg->data, msg->len), msg->l2h[0]);
	hh = (struct ipaccess_head *) msg->data;

	if (hh->proto == IPAC_PROTO_IPACCESS) {
		if (msg->l2h[0] == IPAC_MSGT_ID_RESP) {
			struct tlv_parsed tvp;
			int ret;
			ret = ipaccess_idtag_parse(&tvp,
					     (unsigned char *) msg->l2h + 2,
					     msgb_l2len(msg) - 2);
			if (ret < 0) {
				LOGP(DNAT, LOGL_ERROR, "ignoring IPA response "
					"message with malformed TLVs\n");
				return ret;
			}
			if (TLVP_PRESENT(&tvp, IPAC_IDTAG_UNITNAME))
				ussd_auth_con(&tvp, conn);
		}

		msgb_free(msg);
	} else if (hh->proto == IPAC_PROTO_SCCP) {
		forward_sccp(conn->nat, msg);
	} else {
		msgb_free(msg);
	}

	return 0;
}
Exemple #6
0
static void ussd_auth_cb(void *_data)
{
	LOGP(DNAT, LOGL_ERROR, "USSD module didn't authenticate\n");
	bsc_nat_ussd_destroy((struct bsc_nat_ussd_con *) _data);
}