Changeset 476
- Timestamp:
- 03/17/03 23:35:30 (5 years ago)
- Files:
-
- trunk/RBMessaging/RBMessaging/Client/Connection.py (modified) (1 diff)
- trunk/RBMessaging/RBMessaging/Client/Handlers/Authentication.py (modified) (7 diffs)
- trunk/RBMessaging/RBMessaging/Client/Handlers/Message.py (modified) (1 diff)
- trunk/RBMessaging/RBMessaging/Host/Connection.py (modified) (1 diff)
- trunk/RBMessaging/RBMessaging/Host/Handlers/Authentication.py (modified) (1 diff)
- trunk/RBMessaging/RBMessaging/Host/Handlers/Message.py (modified) (2 diffs)
- trunk/RBMessaging/RBMessaging/Packet/AuthenticationMethods.py (modified) (9 diffs)
- trunk/RBMessaging/demo/simple/all.py (modified) (1 diff)
- trunk/RBMessaging/demo/simple/host.py (modified) (1 diff)
- trunk/RBMessaging/demo/simple/recv.py (modified) (1 diff)
- trunk/RBMessaging/demo/simple/send.py (modified) (1 diff)
- trunk/RBTelepathy/RBTelepathy/Stream/SocketAdaptor.py (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/RBMessaging/RBMessaging/Client/Connection.py
r459 r476 54 54 55 55 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 56 #~ Special 57 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 58 59 def __init__(self, *args, **kw): 60 self.log.debug("Host connection created") 61 super(Connection, self).__init__(*args, **kw) 62 63 def __del__(self): 64 self.log.debug("Client connection destroyed") 65 try: super(Connection, self).__del__() 66 except AttributeError: pass 67 68 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 56 69 #~ Public Methods 57 70 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trunk/RBMessaging/RBMessaging/Client/Handlers/Authentication.py
r467 r476 26 26 from RBTelepathy.Handlers import * 27 27 from RBMessaging.Packet import AuthenticationMethods 28 29 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~30 #~ Constants / Variables / Etc.31 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~32 33 try:34 raise ImportError35 from Crypto.PublicKey import RSA36 import pickle37 sendkey = pickle.load(open('send.rsa'))38 recvkey = pickle.load(open('send.rsa'))39 except ImportError:40 sendkey = None41 recvkey = None42 28 43 29 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 80 66 raise ErrorTypes.AuthenticationError('Sequence type not specified') 81 67 82 print83 print "AuthRecving:", packet.toxml(True)84 print68 #print 69 #print "AuthRecving:", packet.toxml(True) 70 #print 85 71 86 72 try: OnAuthType = self._CallOnAuthType(AuthType) … … 89 75 else: return OnAuthType(packet, *args, **kw) 90 76 91 def AuthorizeAs(self, loginaddr, kind=" response"):77 def AuthorizeAs(self, loginaddr, kind="query"): 92 78 self.loginaddr = URIAddress.URIAddress(loginaddr) 93 79 getattr(self, '_reply_'+kind)(None) 94 80 95 81 def SendPacket(self, packet, *args, **kw): 96 print97 print "AuthSending:", packet.toxml(True)98 print82 #print 83 #print "AuthSending:", packet.toxml(True) 84 #print 99 85 return self.connection.SendPacket(packet, *args, **kw) 100 86 … … 114 100 115 101 def _type_options(self, packet, *args, **kw): 116 print "Available Authentication Types:", [method.type_ for method in packet['method',]]102 #print "Available Authentication Types:", [method.type_ for method in packet['method',]] 117 103 self._reply_select(packet, *args, **kw) 118 104 119 105 def _reply_select(self, packet, *args, **kw): 120 #raise NotImplementedError121 106 response = authentication() 122 107 response.attrs['type'] = 'select' … … 125 110 126 111 # Select method 112 #raise NotImplementedError 127 113 response += AuthenticationMethods.AuthenticationBaseMethod() 128 114 response[-1].attrs['type'] = 'sha-hash' … … 139 125 response[-1].attrs['addr'] = str(self.loginaddr) 140 126 141 if sendkey: 142 # Use PublicKey 143 response += AuthenticationMethods.RSAPublicKey() 144 response[-1].Sign(sendkey, 'password') 145 else: 146 response += AuthenticationMethods.SHAHash() 147 response[-1].Sign('secret', 'password') 127 #response += AuthenticationMethods.Passkey() 128 response += AuthenticationMethods.Plaintext() 129 #response += AuthenticationMethods.MD5Hash() 130 #response += AuthenticationMethods.SHAHash() 131 response[-1].Sign('secret') 148 132 149 133 self.SendPacket(response) … … 161 145 response[-1].attrs['addr'] = str(self.loginaddr) 162 146 163 if sendkey: 164 # Use PublicKey 165 response += AuthenticationMethods.RSAPublicKey() 166 response[-1].Sign(sendkey, 'password') 167 else: 168 response += AuthenticationMethods.SHAHash() 169 response[-1].Sign('secret', 'password') 147 response += AuthenticationMethods.SHAHash() 148 response[-1].Sign('secret')#, 'password') 170 149 171 150 self.SendPacket(response) trunk/RBMessaging/RBMessaging/Client/Handlers/Message.py
r465 r476 44 44 }) 45 45 46 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~47 #~ Public Methods48 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~49 50 def GetAddresses(self, nodename='to'):51 existing = self.iternodes(nodename)52 result = [each.addr for each in existing]53 return result54 55 def SetAddresses(self, addresses, nodename='to'):56 print "XXX: RouteableRootElement.SetAddresses needs work"57 58 46 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 59 47 trunk/RBMessaging/RBMessaging/Host/Connection.py
r459 r476 48 48 49 49 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 50 #~ Special 51 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 52 53 def __init__(self, *args, **kw): 54 self.log.debug("Host connection created") 55 super(Connection, self).__init__(*args, **kw) 56 57 def __del__(self): 58 self.log.debug("Host connection destroyed") 59 try: super(Connection, self).__del__() 60 except AttributeError: pass 61 62 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 50 63 #~ Public Methods 51 64 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trunk/RBMessaging/RBMessaging/Host/Handlers/Authentication.py
r467 r476 103 103 104 104 def GetAccountData(self, asaddr, *args): 105 print "TODO: RBMessaging.Host.Handlers.Authentication.HostAuthentication.GetAccountData" 105 106 return "secret" 106 107 raise ErrorTypes.AuthenticationError('Authentication data not available') trunk/RBMessaging/RBMessaging/Host/Handlers/Message.py
r465 r476 80 80 self.router.AuthorityRoutes[key] = [self.OnRoutedPacket] 81 81 82 def __del__(self): 83 self.log.debug('Message handler destroyed') 84 try: super(HostMessage, self).__del__() 85 except AttributeError: pass 86 82 87 def OnRoutedPacket(self, packet, addresses): 83 88 # Copy the root level packet, so we can adjust it's addresses … … 89 94 90 95 def OnStreamPacket(self, packet): 91 # TODO: Flush out 92 #fromlist = packet.GetAddresses('from') 93 #if fromlist: raise ValueError, '"from" element not allowed on a user connection' 96 fromlist = packet.GetAddresses('from') 97 if len(fromlist) > 1: 98 # Having something sent from more than one address is strange. 99 raise ErrorTypes.PacketMalformedError, 'Only one "from" element allowed.' 100 elif len(fromlist) == 1: 101 # Check to make sure it is from the same account... 102 # TODO: more checks should probably be done 103 if fromlist[0].addr.network != self.connection.loginaddr.network: 104 raise ErrorTypes.PacketMalformedError, 'Invalid "from" address specified.' 105 if fromlist[0].addr.account != self.connection.loginaddr.account: 106 raise ErrorTypes.PacketMalformedError, 'Invalid "from" address specified.' 107 else: 108 from_ = Elements.URIAddressElement('from') 109 from_.addr = str(self.connection.loginaddr) 110 packet.insertelem(0, from_) 94 111 tolist = packet.GetAddresses('to') 95 112 96 self.log.info('Sending "%s" packet to Router', packet.node)97 113 if not self.router: 98 114 self.router = connection.model().GetRouter('message') 99 115 if not self.router: 100 116 raise ErrorTypes.RoutingError, 'No router available' 117 118 self.log.info('Sending "%s" packet to Router', packet.node) 101 119 routecommands = self.router.RoutePacket(packet, tolist) 102 120 if routecommands: trunk/RBMessaging/RBMessaging/Packet/AuthenticationMethods.py
r467 r476 68 68 def _set_challenge(self, challenge): 69 69 self.delnodes('challenge') 70 self.addnode('challenge').adddata(challenge) 70 if challenge: 71 self.addnode('challenge').adddata(challenge) 71 72 def _del_challenge(self): 72 73 self.delnodes('challenge') … … 102 103 raise NotImplementedError 103 104 105 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 106 #~ Protected Methods 107 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 108 109 def _GetTimeMethodChallenge(self, handler, asaddr): 110 challenge = self.challenge 111 try: 112 senttime = time.mktime(DateUtils.fromisoformat(challenge)) 113 except ValueError: 114 return None 115 else: 116 timenow = time.mktime(time.gmtime()) 117 timedelta = abs(timenow - senttime) 118 timedeltawindow = getattr(handler, 'MethodChallengeTimeLimit', 30) 119 if timedelta <= timedeltawindow: 120 return challenge 121 else: 122 raise ErrorTypes.AuthenticationError, 'Authentication challenge utc time is not within valid window. (delta=%r, window=%r)' % (timedelta, timedeltawindow) 123 124 def _SetTimeMethodChallenge(self, astime=None): 125 return DateUtils.isoformat(astime or time.gmtime()) 126 104 127 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 105 128 … … 146 169 147 170 def Sign(self, response=None, challenge=None): 171 if challenge is not None: 172 self.challenge = challenge 148 173 if response is not None: 149 174 self.response = response 150 if challenge is not None:151 self.challenge = challenge152 175 153 176 def SetChallenge(self, handler, asaddr): 154 177 self.response = None 155 self.challenge = "passkey" 156 157 def Verify(self, handler, asaddr): 158 # TODO: Need to verify challenge is valid -- no reply attack 178 self.challenge = None #"passkey" 179 180 def Verify(self, handler, asaddr): 159 181 challenge = self.challenge or '' 160 182 if challenge: … … 184 206 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 185 207 186 def Sign(self, reponse, challenge='password'): 208 def Sign(self, response, challenge='password'): 209 self.challenge = challenge 187 210 self.response = response 188 self.challenge = challenge 211 212 def GetValidChallenge(self, handler, asaddr): 213 challenge = self.challenge 214 try: 215 if challenge == handler.__challenge: 216 return challenge 217 except AttributeError: pass 218 return "password" 189 219 190 220 def SetChallenge(self, handler, asaddr): … … 193 223 194 224 def Verify(self, handler, asaddr): 195 # TODO: Need to verify challenge is valid -- no reply attack196 password = handler.GetAccountData(asaddr, self.challenge or 'password')197 return self.response == password225 challenge = self.GetValidChallenge(handler, asaddr) 226 password = handler.GetAccountData(asaddr, challenge) 227 return self.response.strip() == password.strip() 198 228 except ImportError: 199 229 pass … … 218 248 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 219 249 220 def Sign(self, reponse, challenge): 221 self.challenge = challenge 222 self.response = md5.new(reponse + challenge).hexdigest() 250 def Sign(self, reponse, challenge=None): 251 if challenge is None: 252 self.challenge = self._SetTimeMethodChallenge() 253 else: self.challenge = challenge 254 self.response = md5.new(reponse + self.challenge).hexdigest() 255 256 def GetValidChallenge(self, handler, asaddr): 257 challenge = self.challenge 258 try: 259 if challenge == handler.__challenge: 260 return challenge 261 except AttributeError: pass 262 result = self._GetTimeMethodChallenge(handler, asaddr) 263 if result is not None: return result 264 raise ErrorTypes.AuthenticationError, 'Invalid challenge data' 223 265 224 266 def SetChallenge(self, handler, asaddr): 225 267 self.response = None 226 handler.__challenge = self.challenge = str(id(self) ^ id(handler)) 227 228 def Verify(self, handler, asaddr): 229 # TODO: Need to verify challenge is valid -- no reply attack 268 handler.__challenge = self.challenge = self._SetTimeMethodChallenge() 269 270 def Verify(self, handler, asaddr): 230 271 password = handler.GetAccountData(asaddr, 'md5-password', 'password') 231 correct = md5.new(password + self.challenge).hexdigest() 272 challenge = self.GetValidChallenge(handler, asaddr) 273 correct = md5.new(password + challenge).hexdigest() 232 274 return self.response == correct 233 275 except ImportError: … … 241 283 try: 242 284 import sha 285 import time 286 from RBFoundation import DateUtils 287 243 288 class SHAHash(AuthenticationBaseMethod): 244 289 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 253 298 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 254 299 255 def Sign(self, reponse, challenge): 256 self.challenge = challenge 257 self.response = sha.new(reponse + challenge).hexdigest() 300 def Sign(self, reponse, challenge=None): 301 if challenge is None: 302 self.challenge = self._SetTimeMethodChallenge() 303 else: self.challenge = challenge 304 self.response = sha.new(reponse + self.challenge).hexdigest() 305 306 def GetValidChallenge(self, handler, asaddr): 307 challenge = self.challenge 308 try: 309 if challenge == handler.__challenge: 310 return challenge 311 except AttributeError: pass 312 result = self._GetTimeMethodChallenge(handler, asaddr) 313 if result is not None: return result 314 raise ErrorTypes.AuthenticationError, 'Invalid challenge data' 258 315 259 316 def SetChallenge(self, handler, asaddr): 260 317 self.response = None 261 handler.__challenge = self.challenge = str(id(self) ^ id(handler)) 262 263 def Verify(self, handler, asaddr): 264 # TODO: Need to verify challenge is valid -- no reply attack 318 handler.__challenge = self.challenge = self._SetTimeMethodChallenge() 319 320 def Verify(self, handler, asaddr): 265 321 password = handler.GetAccountData(asaddr, 'sha-password', 'password') 266 correct = sha.new(password + self.challenge).hexdigest() 322 challenge = self.GetValidChallenge(handler, asaddr) 323 correct = sha.new(password + challenge).hexdigest() 267 324 return self.response == correct 268 325 except ImportError: … … 288 345 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 289 346 290 def Sign(self, key, challenge): 291 self.challenge = challenge 347 def Sign(self, key, challenge=None): 348 if challenge is None: 349 self.challenge = self._SetTimeMethodChallenge() 350 else: self.challenge = challenge 292 351 self.response = str(key.sign(self.challenge)[0]) 293 352 353 def GetValidChallenge(self, handler, asaddr): 354 challenge = self.challenge 355 try: 356 if challenge == handler.__challenge: 357 return challenge 358 except AttributeError: pass 359 result = self._GetTimeMethodChallenge(handler, asaddr) 360 if result is not None: return result 361 raise ErrorTypes.AuthenticationError, 'Invalid challenge data' 362 294 363 def SetChallenge(self, handler, asaddr): 295 364 self.response = None 296 handler.__challenge = self.challenge = str(id(self) ^ id(handler)) 297 298 def Verify(self, handler, asaddr): 299 # TODO: Need to verify challenge is valid -- no reply attack 365 handler.__challenge = self.challenge = self._SetTimeMethodChallenge() 366 367 def Verify(self, handler, asaddr): 300 368 key = handler.GetAccountData(asaddr, 'rsa-publickey', 'dsa-publickey', 'publickey') 301 369 signature = long(self.response) 302 return key.verify(self.challenge, (signature,)) 370 challenge = self.GetValidChallenge(handler, asaddr) 371 return key.verify(challenge, (signature,)) 303 372 except ImportError: 304 373 pass trunk/RBMessaging/demo/simple/all.py
r466 r476 33 33 if __name__ == '__main__': 34 34 logging.basicConfig() 35 logging.root.setLevel(logging.INFO)36 #logging.root.setLevel(logging.DEBUG)35 #logging.root.setLevel(logging.INFO) 36 logging.root.setLevel(logging.DEBUG) 37 37 38 38 try: trunk/RBMessaging/demo/simple/host.py
r463 r476 33 33 if __name__ == '__main__': 34 34 logging.basicConfig() 35 logging.root.setLevel(logging.INFO)36 #logging.root.setLevel(logging.DEBUG)35 #logging.root.setLevel(logging.INFO) 36 logging.root.setLevel(logging.DEBUG) 37 37 38 38 try: trunk/RBMessaging/demo/simple/recv.py
r463 r476 33 33 if __name__ == '__main__': 34 34 logging.basicConfig() 35 logging.root.setLevel(logging.INFO)36 #logging.root.setLevel(logging.DEBUG)35 #logging.root.setLevel(logging.INFO) 36 logging.root.setLevel(logging.DEBUG) 37 37 38 38 try: trunk/RBMessaging/demo/simple/send.py
r463 r476 33 33 if __name__ == '__main__': 34 34 logging.basicConfig() 35 logging.root.setLevel(logging.INFO)36 #logging.root.setLevel(logging.DEBUG)35 #logging.root.setLevel(logging.INFO) 36 logging.root.setLevel(logging.DEBUG) 37 37 38 38 try: trunk/RBTelepathy/RBTelepathy/Stream/SocketAdaptor.py
r465 r476 49 49 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 50 50 51 isshutdown = False 51 52 _sendData = None 52 isshutdown = False53 53 _isshutdown_send = False 54 54 _isshutdown_recv = False 55 maxsend = 100000 55 56 log = logging.getLogger('SocketStream') 56 57 … … 80 81 raise ErrorTypes.StreamError('Cannot write to stream after shutdown') 81 82 else: 82 self._sendData.append( [data, len(data)])83 self._sendData.append(data) 83 84 def _delSendData(self): 84 85 del self._sendData … … 87 88 88 89 def send(self, data): 89 self.SendData.append( [data, len(data)])90 self.SendData.append(data) 90 91 write = send 91 92 … … 144 145 145 146 def _ProcessWrite(self, *args, **kw): 146 remaining = self._sendData[0][1] 147 data = self._sendData[0][0] 148 if remaining > 100000: 149 start, end = -remaining, -remaining + 100000 150 nSent = self._SocketSend(data[start:end], *args, **kw) 147 data = self._sendData[0] 148 remaining = len(data) 149 if remaining > self.maxsend: 150 nSent = self._SocketSend(buffer(data, 0, self.maxsend), *args, **kw) 151 151 else: 152 nSent = self._SocketSend(data [-remaining:], *args, **kw)152 nSent = self._SocketSend(data, *args, **kw) 153 153 if nSent is not None: 154 remaining -= nSent 155 if remaining > 0: 156 print ":: Sent", nSent 157 self._sendData[0][1] = remaining 158 else: 159 self._sendData.pop(0) 154 data = buffer(data, nSent) 155 if data: self._sendData[0] = data 156 else: self._sendData.pop(0) 160 157 161 158 if self.isshutdown:
