Question

I am trying to add authentication to a xmlrpc server (which will be running on nodes of a P2P network) without using user:password@host as this will reveal the password to all attackers. The authentication is so to basically create a private network, preventing unauthorised users from accessing it.

My solution to this was to create a challenge response system very similar to this but I have no clue how to add this to the xmlrpc server code. I found a similar question (Where custom authentication was needed) here.

So I tried creating a module that would be called whenever a client connected to the server. This would connect to a challenge-response server running on the client and if the client responded correctly would return True. The only problem was that I could only call the module once and then I got a reactor cannot be restarted error. So is there some way of having a class that whenever the "check()" function is called it will connect and do this?

Would the simplest thing to do be to connect using SSL? Would that protect the password? Although this solution would not be optimal as I am trying to avoid having to generate SSL certificates for all the nodes.

Was it helpful?

Solution 3

For anyone that was looking for a full example below is mine (thanks to Rakis for pointing me in the right direction). In this the user and password is stored in a file called 'passwd' (see the first useful link for more details and how to change it).

Server:

#!/usr/bin/env python
import bjsonrpc
from SRPSocket import SRPSocket
import SocketServer
from bjsonrpc.handlers import BaseHandler
import time

class handler(BaseHandler):
    def time(self):
        return time.time()

class SecureServer(SRPSocket.SRPHost):
    def auth_socket(self, socket):
        server = bjsonrpc.server.Server(socket, handler_factory=handler)
        server.serve()

s = SocketServer.ForkingTCPServer(('', 1337), SecureServer)
s.serve_forever()

Client:

#! /usr/bin/env python
import bjsonrpc
from bjsonrpc.handlers import BaseHandler
from SRPSocket import SRPSocket
import time

class handler(BaseHandler):
    def time(self):
        return time.time()

socket, key = SRPSocket.SRPSocket('localhost', 1337, 'dht', 'testpass')

connection = bjsonrpc.connection.Connection(socket, handler_factory=handler)

test = connection.call.time()
print test
time.sleep(1)

Some useful links:

OTHER TIPS

Don't invent your own authentication scheme. There are plenty of great schemes already, and you don't want to become responsible for doing the security research into what vulnerabilities exist in your invention.

There are two very widely supported authentication mechanisms for HTTP (over which XML-RPC runs, therefore they apply to XML-RPC). One is "Basic" and the other is "Digest". "Basic" is fine if you decide to run over SSL. Digest is more appropriate if you really can't use SSL.

Both are supported by Twisted Web via twisted.web.guard.HTTPAuthSessionWrapper, with copious documentation.

Based on your problem description, it sounds like the Secure Remote Password Protocol might be what you're looking for. It's a password-based mechanism that provides strong, mutual authentication without the complexity of SSL certificate management. It may not be quite as flexible as SSL certificates but it's easy to use and understand (the full protocol description fits on a single page). I've often found it a useful tool for situations where a trusted third party (aka Kerberos/CA authorities) isn't appropriate.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top