[PATCH] openbsc[master]: Add web proxy for control interface

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Max gerrit-no-reply at lists.osmocom.org
Mon Aug 8 11:31:57 UTC 2016


Add web proxy for control interface

Add web application exposing Control Interface over web. Only SET and
GET are fully supported - TRAP support is incomplete at the moment.

Change-Id: I87d40c80061f8b3d02d656ab8cadabbfb871b461
Related: OS#1646
---
A openbsc/contrib/ctrl2sse.py
1 file changed, 140 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/openbsc refs/changes/59/659/2

diff --git a/openbsc/contrib/ctrl2sse.py b/openbsc/contrib/ctrl2sse.py
new file mode 100755
index 0000000..65770eb
--- /dev/null
+++ b/openbsc/contrib/ctrl2sse.py
@@ -0,0 +1,140 @@
+#!/usr/bin/python2
+
+mod_license = """
+/*
+ * Copyright (C) 2016 sysmocom s.f.m.c. GmbH
+ *
+ * All Rights Reserved
+ *
+ * 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 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 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.
+ */
+"""
+
+import sys, argparse, random, logging, tornado.ioloop, tornado.web, tornado.tcpclient, eventsource, bsc_control
+from eventsource import listener
+
+"""
+N. B: this is not an example of building proper REST API or building secure web application.
+It's only purpose is to illustrate conversion of Osmocom's Control Interface to web-friendly API.
+Exposing this to Internet while connected to production network might lead to all sorts of mischief and mayhem
+from NSA' TAO breaking into your network to zombie apocalypse. Do NOT do that.
+"""
+
+stream = None
+
+def read_header(data):
+	t_length = bsc_control.ipa_ctrl_header(data)
+	if (t_length):
+		stream.read_bytes(t_length - 1, callback = read_trap)
+	else:
+		print >> sys.stderr, "protocol error: length missing in %s!" % data
+
+def read_trap(data):
+	(t, z, v, p) = data.split()
+	if (t != 'TRAP' or int(z) != 0):
+		print >> sys.stderr, "protocol error: TRAP != %s or 0! = %d" % (t, int(z))
+	(imsi, ip) = p.split(',')
+	print >> sys.stderr, "X=%s, IMSI=%s, IP=%s" % (v, imsi, ip)
+	stream.read_bytes(4, callback = read_header)
+
+ at tornado.gen.coroutine
+def trap_setup(host, port):
+	global stream
+	stream = yield tornado.tcpclient.TCPClient().connect(host, port)
+	stream.read_bytes(4, callback = read_header)
+
+def d(s, v):
+	return {
+		'interface' : tornado.escape.json_encode(s.getpeername()),
+		'variable' : v,
+		'value' : bsc_control.get_var(s, tornado.escape.native_str(v))
+	}
+
+class CtrlHandler(tornado.web.RequestHandler):
+	'''
+	Return json according to following schema - see http://json-schema.org/documentation.html for details:
+	{
+		"title": "Ctrl Schema",
+		"type": "object",
+		"properties": {
+			"interface": {
+				"type": "string"
+			},
+			"variable": {
+				"type": "string"
+			},
+			"varlue": {
+				"type": "string"
+			}
+		},
+		"required": ["interface", "variable", "value"]
+	}
+	Example validation from command-line:
+	json validate --schema-file=schema.json --document-file=data.json
+	The interface is represented as string because it might look different for IPv4 vs v6.
+	'''
+	def initialize(self):
+		self.skt = bsc_control.connect(self.settings['host'], self.settings['port'])
+
+	def get(self, v):
+		self.write(d(self.skt, v))
+
+	def post(self):
+		self.write(d(self.skt, self.get_argument("variable")))
+
+class SetCtrl(CtrlHandler):
+	def get(self, var, val):
+		bsc_control.set_var(self.skt, tornado.escape.native_str(var), tornado.escape.native_str(val))
+		super(SetCtrl, self).get(tornado.escape.native_str(var))
+
+	def post(self):
+		bsc_control.set_var(self.skt, tornado.escape.native_str(self.get_argument("variable")), tornado.escape.native_str(self.get_argument("value")))
+		super(SetCtrl, self).post()
+
+class Slash(tornado.web.RequestHandler):
+	def get(self):
+		self.write('<html><body>'
+				'<form action="/get" method="POST">'
+					'<input type="text" name="variable">'
+					'<input type="submit" value="GET">'
+				'</form>'
+				'<form action="/set" method="POST">'
+					'<input type="text" name="variable">'
+					'<input type="text" name="value">'
+					'<input type="submit" value="SET">'
+				'</form>'
+				'</body></html>')
+
+if __name__ == '__main__':
+	p = argparse.ArgumentParser(description='Osmocom Control Interface proxy.')
+#        p.add_argument('-c', '--control-port', type = int, default = 4252, help = 'Target Control Interface port')
+	p.add_argument('-c', '--control-port', type = int, default = 4249, help = 'Target Control Interface port')
+	p.add_argument('-a', '--control-host', default = 'localhost', help = 'Target Control Interface adress')
+	p.add_argument('-p', '--port', type = int, default = 6969, help = "Port to bind proxy's web interface")
+	args = p.parse_args()
+	tornado.netutil.Resolver.configure('tornado.netutil.ThreadedResolver') # Use non-blocking resolver
+	logging.basicConfig()
+	application = tornado.web.Application([
+		(r"/", Slash),
+		(r"/get", CtrlHandler),
+		(r"/get/(.*)", CtrlHandler),
+		(r"/set", SetCtrl),
+		(r"/set/(.*)/(.*)", SetCtrl),
+		(r"/sse/(.*)/(.*)", listener.EventSourceHandler, dict(event_class = listener.StringIdEvent, keepalive = 100)),
+	], debug = True, host = args.control_host, port = args.control_port)
+	random.seed()
+	application.listen(args.port)
+	trap_setup(application.settings['host'], 4252)
+	tornado.ioloop.IOLoop.instance().start()

-- 
To view, visit https://gerrit.osmocom.org/659
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I87d40c80061f8b3d02d656ab8cadabbfb871b461
Gerrit-PatchSet: 2
Gerrit-Project: openbsc
Gerrit-Branch: master
Gerrit-Owner: Max <msuraev at sysmocom.de>



More information about the gerrit-log mailing list