#!/usr/bin/env python2 import uuid import pickle import hashlib from xmlrpc.server import SimpleXMLRPCServer from xmlrpc.server import SimpleXMLRPCRequestHandler # Restrict to a particular path. class RequestHandler(SimpleXMLRPCRequestHandler): rpc_paths = ('/RPC2',) # Create server server = SimpleXMLRPCServer(("localhost", 8000), requestHandler=RequestHandler) server.register_introspection_functions() def save_users( users ): pickle.dump( users, open( 'users.data', 'wb' ) ) # Register an instance; all the methods of the instance are # published as XML-RPC methods class CHAP: # initializes class-instance and instance variables # if no userdata exists, it creates a default user def __init__( self ): self.keys = {} self.authenticated = {} try: self.users = pickle.load( open( 'users.data', 'rb' ) ) except FileNotFoundError: self.users = { 'admin': 'Pass123' } save_users( self.users ) # adds a user to dictionary and saves it to a file # won't be executable if not authorized or if user already exists def create_user( self, session, username, password ): if ( self.authenticated.get( session ) == True ): if not username in self.users: self.users[ username ] = password save_users( self.users ) return 'Created user successfully' else: return 'User already exists' else: return 'Sorry, please authenticate first' # tells the server to start the autentification process # and send the generated random salt def init( self ): session = str( uuid.uuid4() ) key = str( uuid.uuid4() ) while session in self.keys: session = str( uuid.uuid4() ) self.keys[ session ] = key return [ session, key ] # checks if send hash is same as internally generated to validate if the correct # password was used def auth( self, session, username, password_hash ): if session in self.keys and username in self.users: combined = self.users.get( username ) + self.keys.get( session ) passhash = hashlib.sha256( combined.encode( 'utf-8' ) ).hexdigest() self.authenticated[ session ] = passhash == password_hash return self.authenticated[ session ] == True else: return False # adds functionality for users to log them selfes off, but also need the # the password_hash to ensure, that nobody else logs you off def logout( self, session, username, password_hash ): if self.auth( session, username, password_hash ): del self.authenticated[ session ] del self.keys[ session ] return self.authenticated.get( session ) != True # a little method that refuses to say hi, if you # are not authenticated def hello( self, session ): if ( self.authenticated.get( session ) == True ): return 'Hi, you are authenticated' else: return 'Sorry, please authenticate first' server.register_instance(CHAP()) # Run the server's main loop server.serve_forever()