1 """RPC Server module."""
6 from fnmatch
import fnmatch
10 # Default verbosity (0 = silent, 1 = print connections, 2 = print requests too)
16 """RPC Server class. Derive a class to implement a particular service."""
18 def __init__(self
, address
, verbose
= VERBOSE
):
19 if type(address
) == type(0):
20 address
= ('', address
)
21 self
._address
= address
22 self
._verbose
= verbose
24 self
._socket
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
25 self
._socket
.bind(address
)
26 self
._socket
.listen(1)
29 def _setverbose(self
, verbose
):
30 self
._verbose
= verbose
41 def _serverloop(self
):
42 while self
._listening
:
46 if self
._verbose
: print "Wait for connection ..."
47 conn
, address
= self
._socket
.accept()
48 if self
._verbose
: print "Accepted connection from %s" % repr(address
)
49 if not self
._verify
(conn
, address
):
50 print "*** Connection from %s refused" % repr(address
)
53 rf
= conn
.makefile('r')
54 wf
= conn
.makefile('w')
58 if self
._verbose
> 1: print "Wait for next request ..."
59 ok
= self
._dorequest
(rf
, wf
)
61 _valid
= ['192.16.201.*', '192.16.197.*', '132.151.1.*', '129.6.64.*']
63 def _verify(self
, conn
, address
):
65 for pat
in self
._valid
:
66 if fnmatch(host
, pat
): return 1
69 def _dorequest(self
, rf
, wf
):
70 rp
= pickle
.Unpickler(rf
)
75 if self
._verbose
> 1: print "Got request: %s" % repr(request
)
77 methodname
, args
, id = request
79 reply
= (None, self
._special
(methodname
, args
), id)
80 elif methodname
[0] == '_':
81 raise NameError, "illegal method name %s" % repr(methodname
)
83 method
= getattr(self
, methodname
)
84 reply
= (None, apply(method
, args
), id)
86 reply
= (sys
.exc_type
, sys
.exc_value
, id)
87 if id < 0 and reply
[:2] == (None, None):
88 if self
._verbose
> 1: print "Suppress reply"
90 if self
._verbose
> 1: print "Send reply: %s" % repr(reply
)
91 wp
= pickle
.Pickler(wf
)
95 def _special(self
, methodname
, args
):
96 if methodname
== '.methods':
97 if not hasattr(self
, '_methods'):
98 self
._methods
= tuple(self
._listmethods
())
100 raise NameError, "unrecognized special method name %s" % repr(methodname
)
102 def _listmethods(self
, cl
=None):
103 if not cl
: cl
= self
.__class
__
104 names
= cl
.__dict
__.keys()
105 names
= filter(lambda x
: x
[0] != '_', names
)
107 for base
in cl
.__bases
__:
108 basenames
= self
._listmethods
(base
)
109 basenames
= filter(lambda x
, names
=names
: x
not in names
, basenames
)
110 names
[len(names
):] = basenames
114 from security
import Security
117 class SecureServer(Server
, Security
):
119 def __init__(self
, *args
):
120 apply(Server
.__init
__, (self
,) + args
)
121 Security
.__init
__(self
)
123 def _verify(self
, conn
, address
):
125 challenge
= self
._generate
_challenge
()
126 conn
.send("%d\n" % challenge
)
128 while "\n" not in response
and len(response
) < 100:
129 data
= conn
.recv(100)
132 response
= response
+ data
134 response
= string
.atol(string
.strip(response
))
135 except string
.atol_error
:
136 if self
._verbose
> 0:
137 print "Invalid response syntax", `response`
139 if not self
._compare
_challenge
_response
(challenge
, response
):
140 if self
._verbose
> 0:
141 print "Invalid response value", `response`
143 if self
._verbose
> 1:
144 print "Response matches challenge. Go ahead!"