diff options
-rwxr-xr-x | contrib/sim-rest-server.py | 118 |
1 files changed, 64 insertions, 54 deletions
diff --git a/contrib/sim-rest-server.py b/contrib/sim-rest-server.py index a31aeed..62498b4 100755 --- a/contrib/sim-rest-server.py +++ b/contrib/sim-rest-server.py @@ -21,7 +21,7 @@ import json import sys import argparse -from klein import run, route +from klein import Klein from pySim.transport import ApduTracer from pySim.transport.pcsc import PcscSimLink @@ -50,78 +50,87 @@ def connect_to_card(slot_nr:int): return tp, scc, card +class ApiError: + def __init__(self, msg:str): + self.msg = msg + + def __str__(self): + return json.dumps({'error': {'message':self.msg}}) + + def set_headers(request): request.setHeader('Content-Type', 'application/json') -@route('/sim-auth-api/v1/slot/<int:slot>') -def auth(request, slot): - """REST API endpoint for performing authentication against a USIM. - Expects a JSON body containing RAND and AUTN. - Returns a JSON body containing RES, CK, IK and Kc.""" - try: - # there are two hex-string JSON parameters in the body: rand and autn - content = json.loads(request.content.read()) - rand = content['rand'] - autn = content['autn'] - except: - request.setResponseCode(400) - return "Malformed Request" - - try: - tp, scc, card = connect_to_card(slot) - except ReaderError: +class SimRestServer: + app = Klein() + + @app.handle_errors(NoCardError) + def no_card_error(self, request, failure): + set_headers(request) + request.setResponseCode(410) + return str(ApiError("No SIM card inserted in slot")) + + @app.handle_errors(ReaderError) + def reader_error(self, request, failure): + set_headers(request) request.setResponseCode(404) - return "Specified SIM Slot doesn't exist" - except ProtocolError: + return str(ApiError("Reader Error: Specified SIM Slot doesn't exist")) + + @app.handle_errors(ProtocolError) + def protocol_error(self, request, failure): + set_headers(request) request.setResponseCode(500) - return "Error" - except NoCardError: - request.setResponseCode(410) - return "No SIM card inserted in slot" + return str(ApiError("Protocol Error")) + + @app.handle_errors(SwMatchError) + def sw_match_error(self, request, failure): + set_headers(request) + request.setResponseCode(500) + return str(ApiError("Card Communication Error %s" % failure)) + + + @app.route('/sim-auth-api/v1/slot/<int:slot>') + def auth(self, request, slot): + """REST API endpoint for performing authentication against a USIM. + Expects a JSON body containing RAND and AUTN. + Returns a JSON body containing RES, CK, IK and Kc.""" + try: + # there are two hex-string JSON parameters in the body: rand and autn + content = json.loads(request.content.read()) + rand = content['rand'] + autn = content['autn'] + except: + set_headers(request) + request.setResponseCode(400) + return str(ApiError("Malformed Request")) + + tp, scc, card = connect_to_card(slot) - try: card.select_adf_by_aid(adf='usim') res, sw = scc.authenticate(rand, autn) - except SwMatchError as e: - request.setResponseCode(500) - return "Communication Error %s" % e - tp.disconnect() + tp.disconnect() - set_headers(request) - return json.dumps(res, indent=4) + set_headers(request) + return json.dumps(res, indent=4) -@route('/sim-info-api/v1/slot/<int:slot>') -def info(request, slot): - """REST API endpoint for obtaining information about an USIM. - Expects empty body in request. - Returns a JSON body containing ICCID, IMSI.""" + @app.route('/sim-info-api/v1/slot/<int:slot>') + def info(self, request, slot): + """REST API endpoint for obtaining information about an USIM. + Expects empty body in request. + Returns a JSON body containing ICCID, IMSI.""" - try: tp, scc, card = connect_to_card(slot) - except ReaderError: - request.setResponseCode(404) - return "Specified SIM Slot doesn't exist" - except ProtocolError: - request.setResponseCode(500) - return "Error" - except NoCardError: - request.setResponseCode(410) - return "No SIM card inserted in slot" - try: card.select_adf_by_aid(adf='usim') iccid, sw = card.read_iccid() imsi, sw = card.read_imsi() res = {"imsi": imsi, "iccid": iccid } - except SwMatchError as e: - request.setResponseCode(500) - return "Communication Error %s" % e - tp.disconnect() + tp.disconnect() - set_headers(request) - return json.dumps(res, indent=4) + set_headers(request) + return json.dumps(res, indent=4) def main(argv): @@ -132,7 +141,8 @@ def main(argv): args = parser.parse_args() - run(args.host, args.port) + srr = SimRestServer() + srr.app.run(args.host, args.port) if __name__ == "__main__": main(sys.argv) |