Exemplo n.º 1
0
def verifyPacket(self, packet):
	plen = len(packet)
	
	
	# Check the number of sections
	if plen == self.MAX_SECTIONS:
		# Check the header
		if packet[self.SECTION_HEADER] == self.PROTOCOL_HEADER:
			# Check the version number (must be exact versions for now)
			if packet[self.SECTION_VERSION] == self.PROTOCOL_VERSION:
				# Check the checksum
				verify = packet[self.SECTION_SOURCE] + self.SECTION_SEPERATOR + packet[self.SECTION_VIA] + self.SECTION_SEPERATOR + packet[self.SECTION_DESTINATION] + self.SECTION_SEPERATOR + packet[self.SECTION_FLAGS] + self.SECTION_SEPERATOR + packet[self.SECTION_APPLICATION_ID] + self.SECTION_SEPERATOR + packet[self.SECTION_PACKET_ID] + self.SECTION_SEPERATOR + packet[self.SECTION_DATA]
				checksum = self.sha1(verify + self.SECTION_SEPERATOR + packet[self.SECTION_SIGNATURE])
				
				# Convert the flags to old-style
				packet[self.SECTION_FLAGS] = bin(int(packet[self.SECTION_FLAGS], 16)).replace("0b", "").rjust(16, "0")
				
				
				if checksum == packet[self.SECTION_CHECKSUM]:
					
					# Application ID
					if self.REPEATER_MODE:
						# Set the application ID to the one we are verifying
						self.APPLICATION_ID = packet[self.SECTION_APPLICATION_ID]
					
					
					if packet[self.SECTION_APPLICATION_ID] == self.APPLICATION_ID:
						
						# Packet replay detection
						if not packet[self.SECTION_PACKET_ID] in self.prd:
							if self.DEBUG_MODE:
								self.log.info("Packet ID %s not present in PRD database, adding it in." % packet[self.SECTION_PACKET_ID])
							
							self.prd[packet[self.SECTION_PACKET_ID]] = packet[self.SECTION_SOURCE]
							
							
							# Callsign signature
							if self.CRYPTO_AVAILABLE:
								if len(str(packet[self.SECTION_SIGNATURE]).replace("\x00", "")) > 0:
									client_key = os.path.join(self.CRYPTO_REMOTE_DIRECTORY, "%s.key" % self.sha1(packet[self.SECTION_SOURCE]))
									
									if os.path.exists(client_key):
										if self.DEBUG_MODE:
											self.log.info("Verifying the packet using the public key for %s..." % packet[self.SECTION_SOURCE])
										
										
										test = DanRSA(client_key, None, None)
										result = test.verifyMessage(verify, self.decodeBase128ToStream(packet[self.SECTION_SIGNATURE], 0, True))
										test = None
										
										if result:
											if self.DEBUG_MODE:
												self.log.info("The signature has validated using the public key for %s." % packet[self.SECTION_SOURCE])
											
										else:
											if self.DEBUG_MODE:
												self.log.warn("The signature did NOT validate using the public key for %s." % packet[self.SECTION_SOURCE])
										
										return result
										
									else:
										if self.DEBUG_MODE:
											self.log.warn("We do not have the public key for %s (%s.key), cannot verify the packet." % (packet[self.SECTION_SOURCE], self.sha1(packet[self.SECTION_SOURCE])))
										
										
										if self.CRYPTO_ALLOW_UNSIGNED_PACKETS:
											return True
									
								else:
									if self.DEBUG_MODE:
										self.log.warn("Packet contained no signature.")
									
									
									if self.CRYPTO_ALLOW_UNSIGNED_PACKETS:
										return True
								
							else:
								if self.DEBUG_MODE:
									self.log.warn("Crypto isn't available so we can't validate the signature.")
								
								
								if self.CRYPTO_ALLOW_UNSIGNED_PACKETS:
									return True
							
						else:
							if self.DEBUG_MODE:
								self.log.warn("Packet replay detected by %s." % self.prd[packet[self.SECTION_PACKET_ID]])
						
					else:
						if self.DEBUG_MODE:
							self.log.warn("The packet received application ID (%s) isn't for this application." % packet[self.SECTION_APPLICATION_ID])
					
				else:
					if self.DEBUG_MODE:
						self.log.warn("Checksum mismatch (%s != %s)." % (checksum, packet[self.SECTION_CHECKSUM]))
				
			else:
				if self.DEBUG_MODE:
					self.log.warn("Version number mismatch (%s != %s)." % (self.PROTOCOL_VERSION, packet[self.SECTION_VERSION]))
			
		else:
			if self.DEBUG_MODE:
				self.log.warn("Invalid header (%s != %s)." % (self.PROTOCOL_HEADER, packet[self.SECTION_HEADER]))
		
	else:
		if self.DEBUG_MODE:
			self.log.warn("Wrong number of sections (%d != %d)." % (plen, self.MAX_SECTIONS))
	
	return False
Exemplo n.º 2
0
def splitPacket(self, packet):
	if self.DEBUG_MODE:
		self.log.info("Running...")
	
	
	plen = len(packet)
	
	if plen >= 80:
		# We need to validate the checksum here while we've got the raw packet
		checksum = bytearray()
		
		checksum.extend(packet[10:20]) # Source callsign
		checksum.extend(packet[20:30]) # Via
		checksum.extend(packet[30:40]) # Destination callsign
		checksum.extend(packet[40:42]) # Flags
		checksum.extend(packet[42:62]) # Application ID
		checksum.extend(packet[62:82]) # Packet ID
		checksum.extend(packet[82:plen - 26]) # Data (excluding the checksum of course)
		
		if self.encodeNumberToBase(int(self.sha1(str(checksum)), 16)).rjust(20, "\x00") == packet[plen - 26:plen - 6]:
			# OK, build a "old-style" list to keep compatibility
			ret = []
			ret.append(packet[0:6]) # Header
			ret.append(packet[6:10]) # Version
			ret.append(packet[10:20].replace("\x00", "")) # Source callsign
			ret.append(packet[20:30].replace("\x00", "")) # Via
			ret.append(packet[30:40].replace("\x00", "")) # Destination callsign
			ret.append(bin(self.decodeBaseToNumber(packet[40:42])).replace("0b", "").rjust(16, "0")) # Flags
			ret.append(str(hex(self.decodeBaseToNumber(packet[42:62]))).replace("0x", "").replace("L", "")) # Application ID
			ret.append(str(hex(self.decodeBaseToNumber(packet[62:82]))).replace("0x", "").replace("L", "")) # Packet ID
			ret.append(packet[82:plen - 90]) # Data
			ret.append(packet[plen - 90:plen - 26]) # Signature
			ret.append(self.sha1(str(self.decodeBaseToNumber(packet[plen - 26:plen - 6])))) # Checksum
			ret.append(packet[plen - 6:plen]) # Footer
			
			
			if self.CRYPTO_AVAILABLE:
				# Check the callsign signature
				verify = bytearray()
				verify.extend(packet[10:20]) # Source callsign
				verify.extend(packet[20:30]) # Via
				verify.extend(packet[30:40]) # Destination callsign
				verify.extend(packet[40:42]) # Flags
				verify.extend(packet[42:62]) # Application ID
				verify.extend(packet[62:82]) # Packet ID
				verify.extend(packet[82:plen - 90]) # Data
				
				
				if len(str(ret[self.SECTION_SIGNATURE]).replace("\x00", "")) > 0:
					client_key = os.path.join(self.CRYPTO_REMOTE_DIRECTORY, "%s.key" % self.sha1(ret[self.SECTION_SOURCE]))
					
					if os.path.exists(client_key):
						if self.DEBUG_MODE:
							self.log.info("Verifying the packet using the public key for %s..." % ret[self.SECTION_SOURCE])
						
						
						test = DanRSA(client_key, None, None)
						result = test.verifyMessage(str(verify), ret[self.SECTION_SIGNATURE])
						test = None
						
						if result:
							if self.DEBUG_MODE:
								self.log.info("The signature has validated using the public key for %s." % ret[self.SECTION_SOURCE])
							
						else:
							if self.DEBUG_MODE:
								self.log.warn("The signature did NOT validate using the public key for %s." % ret[self.SECTION_SOURCE])
						
						return ret
						
					else:
						if self.DEBUG_MODE:
							self.log.warn("We do not have the public key for %s (%s.key), cannot verify the packet." % (ret[self.SECTION_SOURCE], self.sha1(ret[self.SECTION_SOURCE])))
						
						
						if self.CRYPTO_ALLOW_UNSIGNED_PACKETS:
							return ret
							
						else:
							return None
					
				else:
					if self.DEBUG_MODE:
						self.log.warn("Packet contained no signature.")
					
					
					if self.CRYPTO_ALLOW_UNSIGNED_PACKETS:
						return ret
						
					else:
						return None
				
			else:
				if self.DEBUG_MODE:
					self.log.warn("Crypto isn't available so we can't validate the signature.")
				
				
				if self.CRYPTO_ALLOW_UNSIGNED_PACKETS:
					return ret
					
				else:
					return None
			
		else:
			if self.DEBUG_MODE:
				self.log.warn("Packet checksum mismatch.")
			
			return None
		
	else:
		if self.DEBUG_MODE:
			self.log.warn("Packet length mismatch (%d != %d)." % (plen, 68))
		
		return None