Esempio n. 1
0
    def handle_relay_begin_cell(self, cell_bytes, direction):
        begin_cell = Parser.parse_encoded_begin_cell(cell_bytes)
        recognized, begin_cell = Processor.process_begin_cell(
            begin_cell, self.session_key)

        if recognized == 0:
            print("Recognized the begin cell!")

            # Getting the IP and port
            addrport = bytearray(begin_cell.PAYLOAD.Data.ADDRPORT)
            ip_addr, port = unpack('!IH', addrport)
            ip_addr = str(IPv4Address(ip_addr))

            # Appending the stream ID to this circuit
            stream_id = begin_cell.PAYLOAD.StreamID
            self.stream_ids.append(stream_id)

            # Creating the socket and connecting it to end host! F**k yeah
            conn = self.stream_skts[stream_id] = HTTPConnection(ip_addr, port)
            conn.request("GET", "/")
            res = conn.getresponse()
            print(res.status, res.reason)
            if res:
                # The last parameter for build_relay_connected_cell is supposed to be TTL in secs
                connected_cell = Builder.build_relay_connected_cell(
                    self.circ_id, stream_id, self.session_key, ip_addr, 360)
                self.conn.sendall(ComplexStructEncoder.encode(connected_cell))

        else:
            print("Begin cell not for us. Lets pass it on!")
            self.skt.client_send_data(ComplexStructEncoder.encode(begin_cell))
Esempio n. 2
0
    def create_circuit_hop2(self) -> int:
        """
		The function to setup circuit with the second hop in the circuit. Creates the EXTEND/EXTEND2 cell and sends it
		down the socket. It assumes that the open_connection was called on the first node and the socket is connected
		to the first node, and that to the second node
		:return: Returns a status code. 0 --> Success DH Handshake and -1 --> Means error in processing the cell or the DH Handshake.
		On error it closes the socket to node 2.
		"""
        # First create a EXTEND2 Cell.
        x, x_bytes, gx, gx_bytes = CoreCryptoDH.generate_dh_priv_key()

        # For hop2 we get its IP:port for LSPEC ==> Link specifier
        hop2_ip = self.node_container[2].host
        hop2_port = self.node_container[2].port
        extend_cell = Builder.build_extend_cell(
            'TAP', x_bytes, gx_bytes, self.circ_id,
            self.node_container[2].onion_key_pub, hop2_ip, hop2_port)

        print(extend_cell)

        # Sending a JSON String down the socket
        self.skt.client_send_data(ComplexStructEncoder.encode(extend_cell))

        # Get the extended cell in response and convert it to python Cell Object
        cell_bytes = self.skt.client_recv_data()
        extended_cell = Parser.parse_encoded_extended_cell(cell_bytes)

        self.session_key02 = Processor.process_extended_cell(
            extended_cell, self.circ_id, x_bytes)
        if self.session_key02 is None:
            self.skt.close()
            return -1

        return 0
Esempio n. 3
0
    def create_circuit_hop1(self) -> int:
        """
		The function to setup circuit with the first hop in the circuit. Creates the CREATE/CREATE2 cell and sends it
		down the socket. It assumes that the open_connection was called on the first node and the socket is connected
		to the first node
		:return: Returns a status code. 0 --> Success DH Handshake and -1 --> Means error in processing the cell or the DH Handshake.
		On error it closes the socket to node 1
		"""
        # First create a CREATE2 Cell.
        x, x_bytes, gx, gx_bytes = CoreCryptoDH.generate_dh_priv_key()
        create_cell = Builder.build_create_cell(
            'TAP', x_bytes, gx_bytes, self.circ_id,
            self.node_container[1].onion_key_pub)

        # Sending a JSON String down the socket
        self.skt.client_send_data(ComplexStructEncoder.encode(create_cell))
        # self.skt.client_send_data(Serialize.obj_to_json(create_cell).encode('utf-8'))

        # Get the created cell in response and convert it to python Cell Object
        cell_bytes = self.skt.client_recv_data()
        created_cell = Parser.parse_encoded_created_cell(cell_bytes)

        self.session_key01 = Processor.process_created_cell(
            created_cell, self.circ_id, x_bytes)
        if self.session_key01 is None:
            self.skt.close()
            return -1

        return 0
Esempio n. 4
0
    def handle_relay_extend_cell(self, cell_bytes, direction):
        if self.is_last_node:
            extend_cell = Parser.parse_encoded_extend_cell(cell_bytes)
            addr, port, htype, hlen, hdata = Processor.process_extend_cell(
                extend_cell, self.node.onion_key_pri)

            # Connect with next node
            print(addr, port)
            err_code = self.skt.client_connect(addr, port)
            print(err_code)

            # Successfully connected, register it to the selectors list
            if err_code == 0:
                self.sktSelector.register(self.skt.skt, selectors.EVENT_READ,
                                          1)

            # Create a CREATE2 Cell.
            create_cell = Builder.build_create_cell_from_extend(
                self.circ_id, htype, hlen, hdata)

            # Sending a JSON String down the socket
            self.skt.client_send_data(ComplexStructEncoder.encode(create_cell))

            return 1
        else:
            # Forwarding the cell down the stream
            self.skt.client_send_data(cell_bytes)

            return 2
Esempio n. 5
0
	def handle_relay_connected_cell(self, cell_bytes, direction):
		"""
		Function for handling the connected cell when it is received by a router
		:param cell_bytes: The struct received by the router for the connected cell
		"""
		parsed_connected_cell = Parser.parse_encoded_connected_cell(cell_bytes)
		processed_connected_cell = Processor.process_connected_cell_router(parsed_connected_cell, self.session_key)
		self.conn.sendall(ComplexStructEncoder.encode(processed_connected_cell))
		return
Esempio n. 6
0
    def make_request(self):

        head_request_str = "HEAD /index.html"
        relay_data_cell = Builder.build_relay_data_cell(
            head_request_str, self.circ_id, 0, 1, self.session_key01,
            self.session_key02, self.session_key03)

        self.skt.client_send_data(ComplexStructEncoder.encode(relay_data_cell))

        return 0
Esempio n. 7
0
	def handle_created_cell(self, cell_bytes, direction):
		created_cell = Parser.parse_encoded_created_cell(cell_bytes)

		# process created cell
		hlen, hdata = Processor.process_created_cell_for_extended(created_cell)

		# Create extended cell
		extended_cell = Builder.build_extended_cell_from_created_cell(self.circ_id, hlen, hdata)

		# send extended to conn
		self.conn.sendall(ComplexStructEncoder.encode(extended_cell))
		self.is_last_node = False
		print("Extended cell sent")
Esempio n. 8
0
	def handle_create_cell(self, cell_bytes, direction):
			# Call the Parser for create cell
			create_cell = Parser.parse_encoded_create_cell(cell_bytes)

			# Process the create cell
			y, y_bytes, gy, gy_bytes = CoreCryptoDH.generate_dh_priv_key()
			gx_bytes, kdf_dict = Processor.process_create_cell(create_cell, self.node.onion_key_pri, y_bytes)

			# After processing the create cell, we make a created cell
			# and send it down the socket
			created_cell = Builder.build_created_cell(y_bytes, gy_bytes, self.circ_id, gx_bytes)
			print(created_cell)
			self.conn.sendall(ComplexStructEncoder.encode(created_cell))
			print("Created cell sent")

			self.session_key = kdf_dict
			return 0
Esempio n. 9
0
	def handle_relay_data_cell(self, cell_bytes, direction):
		"""
		Function for handling the data cell when received by a router
		:param cell_bytes: The struct received by the router for the data cell
		:param direction:
		:return:
		"""
		parsed_relay_data_cell = Parser.parse_encoded_relay_data_cell(cell_bytes)
		recognized, http_request_payload, relay_data_cell = Processor.process_relay_data_cell(parsed_relay_data_cell, self.session_key)
		if recognized == 0 and direction == 0:
			stream_id = relay_data_cell.PAYLOAD.StreamID
			conn = self.stream_skts[stream_id]
			conn.request(http_request_payload['method'], http_request_payload['url'])
			res = conn.getresponse()
			print(res.status, res.reason)
			return
		elif recognized != 0 and direction == 0:
			print("Not for me! Pass it on")
			self.skt.client_send_data(ComplexStructEncoder.encode(relay_data_cell))
			return
		else:
			print("shouldn't reach here at this stage")
			return
Esempio n. 10
0
    def begin_end_destination_stream(self, ip_addr: str, port: int = 80):

        addrport = pack('!IH', int(ip_address(ip_addr)), port)
        flag_dict = {
            'IPV6_PREF': 0,
            'IPV4_NOT_OK': 0,
            'IPV6_OK': 1
        }  # Need to set the flag according to the spec. But for now its fine

        # Build a begin cell to send to the exit node
        begin_cell = Builder.build_begin_cell(addrport, flag_dict,
                                              self.circ_id, 0, 1,
                                              self.session_key01,
                                              self.session_key02,
                                              self.session_key03)

        # Send the begin cell down the first hop
        # Sending a JSON String down the socket
        self.skt.client_send_data(ComplexStructEncoder.encode(begin_cell))

        # Wait for the relay_connected cell to arrive
        # Get the relay_connected cell in response and convert it to python Cell Object
        cell_bytes = self.skt.client_recv_data()
        relay_connected_cell_parsed = Parser.parse_encoded_connected_cell(
            cell_bytes)
        relay_connected_cell = Processor.process_connected_cell_proxy(
            relay_connected_cell_parsed, self.session_key01,
            self.session_key02, self.session_key03)

        print(vars(relay_connected_cell))
        print(vars(relay_connected_cell.PAYLOAD))
        print(vars(relay_connected_cell.PAYLOAD.Data))
        if relay_connected_cell is not None:
            return 0
        else:
            return -1