annotate Demo/pdist/server.py @ 5817:48b94de85bf3 legacy-trunk

Extensive changes by AMK.
author Guido van Rossum <guido@python.org>
date Thu, 17 Jul 1997 16:29:42 +0000
parents a0a4afa39d7a
children 71a294bd7950
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2652
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
1 """RPC Server module."""
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
2
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
3 import sys
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
4 import socket
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
5 import pickle
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
6 from fnmatch import fnmatch
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
7 from repr import repr
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
8
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
9
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
10 # Default verbosity (0 = silent, 1 = print connections, 2 = print requests too)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
11 VERBOSE = 1
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
12
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
13
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
14 class Server:
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
15
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
16 """RPC Server class. Derive a class to implement a particular service."""
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
17
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
18 def __init__(self, address, verbose = VERBOSE):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
19 if type(address) == type(0):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
20 address = ('', address)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
21 self._address = address
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
22 self._verbose = verbose
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
23 self._socket = None
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
24 self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
25 self._socket.bind(address)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
26 self._socket.listen(1)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
27 self._listening = 1
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
28
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
29 def _setverbose(self, verbose):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
30 self._verbose = verbose
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
31
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
32 def __del__(self):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
33 self._close()
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
34
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
35 def _close(self):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
36 self._listening = 0
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
37 if self._socket:
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
38 self._socket.close()
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
39 self._socket = None
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
40
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
41 def _serverloop(self):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
42 while self._listening:
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
43 self._serve()
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
44
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
45 def _serve(self):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
46 if self._verbose: print "Wait for connection ..."
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
47 conn, address = self._socket.accept()
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
48 if self._verbose: print "Accepted connection from %s" % repr(address)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
49 if not self._verify(conn, address):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
50 print "*** Connection from %s refused" % repr(address)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
51 conn.close()
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
52 return
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
53 rf = conn.makefile('r')
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
54 wf = conn.makefile('w')
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
55 ok = 1
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
56 while ok:
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
57 wf.flush()
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
58 if self._verbose > 1: print "Wait for next request ..."
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
59 ok = self._dorequest(rf, wf)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
60
2768
a0a4afa39d7a import string; add 129.6.64 to security
Guido van Rossum <guido@python.org>
parents: 2763
diff changeset
61 _valid = ['192.16.201.*', '192.16.197.*', '132.151.1.*', '129.6.64.*']
2652
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
62
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
63 def _verify(self, conn, address):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
64 host, port = address
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
65 for pat in self._valid:
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
66 if fnmatch(host, pat): return 1
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
67 return 0
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
68
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
69 def _dorequest(self, rf, wf):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
70 rp = pickle.Unpickler(rf)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
71 try:
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
72 request = rp.load()
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
73 except EOFError:
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
74 return 0
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
75 if self._verbose > 1: print "Got request: %s" % repr(request)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
76 try:
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
77 methodname, args, id = request
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
78 if '.' in methodname:
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
79 reply = (None, self._special(methodname, args), id)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
80 elif methodname[0] == '_':
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
81 raise NameError, "illegal method name %s" % repr(methodname)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
82 else:
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
83 method = getattr(self, methodname)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
84 reply = (None, apply(method, args), id)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
85 except:
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
86 reply = (sys.exc_type, sys.exc_value, id)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
87 if id < 0 and reply[:2] == (None, None):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
88 if self._verbose > 1: print "Suppress reply"
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
89 return 1
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
90 if self._verbose > 1: print "Send reply: %s" % repr(reply)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
91 wp = pickle.Pickler(wf)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
92 wp.dump(reply)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
93 return 1
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
94
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
95 def _special(self, methodname, args):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
96 if methodname == '.methods':
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
97 if not hasattr(self, '_methods'):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
98 self._methods = tuple(self._listmethods())
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
99 return self._methods
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
100 raise NameError, "unrecognized special method name %s" % repr(methodname)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
101
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
102 def _listmethods(self, cl=None):
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
103 if not cl: cl = self.__class__
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
104 names = cl.__dict__.keys()
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
105 names = filter(lambda x: x[0] != '_', names)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
106 names.sort()
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
107 for base in cl.__bases__:
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
108 basenames = self._listmethods(base)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
109 basenames = filter(lambda x, names=names: x not in names, basenames)
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
110 names[len(names):] = basenames
d6350a318997 commit -- why not
Guido van Rossum <guido@python.org>
parents:
diff changeset
111 return names
2763
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
112
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
113
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
114 from security import Security
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
115
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
116
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
117 class SecureServer(Server, Security):
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
118
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
119 def __init__(self, *args):
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
120 apply(Server.__init__, (self,) + args)
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
121 Security.__init__(self)
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
122
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
123 def _verify(self, conn, address):
2768
a0a4afa39d7a import string; add 129.6.64 to security
Guido van Rossum <guido@python.org>
parents: 2763
diff changeset
124 import string
2763
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
125 challenge = self._generate_challenge()
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
126 conn.send("%d\n" % challenge)
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
127 response = ""
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
128 while "\n" not in response and len(response) < 100:
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
129 data = conn.recv(100)
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
130 if not data:
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
131 break
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
132 response = response + data
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
133 try:
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
134 response = string.atol(string.strip(response))
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
135 except string.atol_error:
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
136 if self._verbose > 0:
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
137 print "Invalid response syntax", `response`
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
138 return 0
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
139 if not self._compare_challenge_response(challenge, response):
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
140 if self._verbose > 0:
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
141 print "Invalid response value", `response`
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
142 return 0
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
143 if self._verbose > 1:
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
144 print "Response matches challenge. Go ahead!"
b9548960f945 security stuff added
Guido van Rossum <guido@python.org>
parents: 2671
diff changeset
145 return 1