def testRdfFormatter(self): """Hints format RDF values with arbitrary values and attributes.""" # Create a complex RDF value rdf = rdf_client.ClientSummary() rdf.system_info.system = "Linux" rdf.system_info.fqdn = "coreai.skynet.com" # Users (repeated) rdf.users = [rdf_client.User(username=u) for u in ("root", "jconnor")] # Interface (nested, repeated) addresses = [ rdf_client_network.NetworkAddress(human_readable_address=a) for a in ("1.1.1.1", "2.2.2.2", "3.3.3.3") ] eth0 = rdf_client_network.Interface(ifname="eth0", addresses=addresses[:2]) ppp0 = rdf_client_network.Interface(ifname="ppp0", addresses=addresses[2:3]) rdf.interfaces = [eth0, ppp0] template = ( "{system_info.system} {users.username} {interfaces.ifname} " "{interfaces.addresses.human_readable_address}\n") hinter = hints.Hinter(template=template) expected = "Linux root,jconnor eth0,ppp0 1.1.1.1,2.2.2.2,3.3.3.3" result = hinter.Render(rdf) self.assertEqual(expected, result)
def testClientSummaryToExportedNetworkInterfaceConverter(self): mac_address_bytes = b"123456" mac_address = text.Hexify(mac_address_bytes) summary = rdf_client.ClientSummary(interfaces=[ rdf_client_network.Interface( mac_address=mac_address_bytes, ifname="eth0", addresses=[ rdf_client_network.NetworkAddress( address_type=rdf_client_network.NetworkAddress.Family.INET, packed_bytes=socket.inet_pton(socket.AF_INET, "127.0.0.1"), ), rdf_client_network.NetworkAddress( address_type=rdf_client_network.NetworkAddress.Family.INET, packed_bytes=socket.inet_pton(socket.AF_INET, "10.0.0.1"), ), rdf_client_network.NetworkAddress( address_type=rdf_client_network.NetworkAddress.Family.INET6, packed_bytes=socket.inet_pton(socket.AF_INET6, "2001:720:1500:1::a100"), ) ]) ]) converter = client_summary.ClientSummaryToExportedNetworkInterfaceConverter( ) results = list(converter.Convert(self.metadata, summary)) self.assertLen(results, 1) self.assertEqual(results[0].mac_address, mac_address) self.assertEqual(results[0].ifname, "eth0") self.assertEqual(results[0].ip4_addresses, "127.0.0.1 10.0.0.1") self.assertEqual(results[0].ip6_addresses, "2001:720:1500:1::a100")
def EnumerateInterfacesFromClient(args): """Enumerate all MAC addresses of all NICs. Args: args: Unused. Yields: `rdf_client_network.Interface` instances. """ del args # Unused. pythoncom.CoInitialize() for interface in wmi.WMI().Win32_NetworkAdapterConfiguration(): addresses = [] for ip_address in interface.IPAddress or []: addresses.append( rdf_client_network.NetworkAddress( human_readable_address=ip_address)) response = rdf_client_network.Interface(ifname=interface.Description) if interface.MACAddress: response.mac_address = binascii.unhexlify( interface.MACAddress.replace(":", "")) if addresses: response.addresses = addresses yield response
def ParseMultiple(self, result_dicts): """Parse the WMI packages output.""" for result_dict in result_dicts: args = {"ifname": result_dict["Description"]} args["mac_address"] = binascii.unhexlify( result_dict["MACAddress"].replace(":", "")) self._ConvertIPs([("IPAddress", "addresses"), ("DefaultIPGateway", "ip_gateway_list"), ("DHCPServer", "dhcp_server_list")], result_dict, args) if "DHCPLeaseExpires" in result_dict: args["dhcp_lease_expires"] = self.WMITimeStrToRDFDatetime( result_dict["DHCPLeaseExpires"]) if "DHCPLeaseObtained" in result_dict: args["dhcp_lease_obtained"] = self.WMITimeStrToRDFDatetime( result_dict["DHCPLeaseObtained"]) yield rdf_client_network.Interface(**args) yield rdf_client_network.DNSClientConfiguration( dns_server=result_dict["DNSServerSearchOrder"], dns_suffix=result_dict["DNSDomainSuffixSearchOrder"])
def _SetupClients(self, n): res = {} for i in range(1, n + 1): client_id = "C.100000000000000%d" % i client = rdf_objects.ClientSnapshot(client_id=client_id) client.knowledge_base.os = "Windows" client.knowledge_base.fqdn = "host-%d.example.com" % i client.interfaces = [ rdf_client_network.Interface( addresses=[ rdf_client_network.NetworkAddress( address_type=rdf_client_network.NetworkAddress.Family. INET, packed_bytes=ipv6_utils.InetPtoN(socket.AF_INET, "192.168.0.%d" % i)), rdf_client_network.NetworkAddress( address_type=rdf_client_network.NetworkAddress.Family. INET6, packed_bytes=ipv6_utils.InetPtoN(socket.AF_INET6, "2001:abcd::%d" % i)) ], mac_address=("aabbccddee0%d" % i).decode("hex")) ] res[client_id] = client return res
def EnumerateInterfacesFromClient(args): """Enumerate all MAC addresses.""" del args # Unused libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library("c")) ifa = Ifaddrs() p_ifa = ctypes.pointer(ifa) libc.getifaddrs(ctypes.pointer(p_ifa)) addresses = {} macs = {} ifs = set() m = p_ifa while m: ifname = ctypes.string_at(m.contents.ifa_name) ifs.add(ifname) try: iffamily = ord(m.contents.ifa_addr[1]) if iffamily == 0x2: # AF_INET data = ctypes.cast(m.contents.ifa_addr, ctypes.POINTER(Sockaddrin)) ip4 = "".join(map(chr, data.contents.sin_addr)) address_type = rdf_client_network.NetworkAddress.Family.INET address = rdf_client_network.NetworkAddress( address_type=address_type, packed_bytes=ip4) addresses.setdefault(ifname, []).append(address) if iffamily == 0x12: # AF_LINK data = ctypes.cast(m.contents.ifa_addr, ctypes.POINTER(Sockaddrdl)) iflen = data.contents.sdl_nlen addlen = data.contents.sdl_alen macs[ifname] = "".join( map(chr, data.contents.sdl_data[iflen:iflen + addlen])) if iffamily == 0x1E: # AF_INET6 data = ctypes.cast(m.contents.ifa_addr, ctypes.POINTER(Sockaddrin6)) ip6 = "".join(map(chr, data.contents.sin6_addr)) address_type = rdf_client_network.NetworkAddress.Family.INET6 address = rdf_client_network.NetworkAddress( address_type=address_type, packed_bytes=ip6) addresses.setdefault(ifname, []).append(address) except ValueError: # Some interfaces don't have a iffamily and will raise a null pointer # exception. We still want to send back the name. pass m = m.contents.ifa_next libc.freeifaddrs(p_ifa) for interface in ifs: mac = macs.setdefault(interface, "") address_list = addresses.setdefault(interface, "") args = {"ifname": interface} if mac: args["mac_address"] = mac if address_list: args["addresses"] = address_list yield rdf_client_network.Interface(**args)
def EnumerateInterfacesFromClient(args): """Enumerate all interfaces and collect their MAC addresses.""" del args # Unused libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library("c")) ifa = Ifaddrs() p_ifa = ctypes.pointer(ifa) libc.getifaddrs(ctypes.pointer(p_ifa)) addresses = {} macs = {} ifs = set() m = p_ifa while m: ifname = ctypes.string_at(m.contents.ifa_name) ifs.add(ifname) try: iffamily = ord(m.contents.ifa_addr[0]) # TODO(hanuszczak): There are some Python 3-incompatible `chr` usages # here, they should be fixed. if iffamily == 0x2: # AF_INET data = ctypes.cast(m.contents.ifa_addr, ctypes.POINTER(Sockaddrin)) ip4 = bytes(list(data.contents.sin_addr)) address_type = rdf_client_network.NetworkAddress.Family.INET address = rdf_client_network.NetworkAddress( address_type=address_type, packed_bytes=ip4) addresses.setdefault(ifname, []).append(address) if iffamily == 0x11: # AF_PACKET data = ctypes.cast(m.contents.ifa_addr, ctypes.POINTER(Sockaddrll)) addlen = data.contents.sll_halen macs[ifname] = bytes(list(data.contents.sll_addr[:addlen])) if iffamily == 0xA: # AF_INET6 data = ctypes.cast(m.contents.ifa_addr, ctypes.POINTER(Sockaddrin6)) ip6 = bytes(list(data.contents.sin6_addr)) address_type = rdf_client_network.NetworkAddress.Family.INET6 address = rdf_client_network.NetworkAddress( address_type=address_type, packed_bytes=ip6) addresses.setdefault(ifname, []).append(address) except ValueError: # Some interfaces don't have a iffamily and will raise a null pointer # exception. We still want to send back the name. pass m = m.contents.ifa_next libc.freeifaddrs(p_ifa) for interface in ifs: mac = macs.setdefault(interface, b"") address_list = addresses.setdefault(interface, b"") args = {"ifname": interface} if mac: args["mac_address"] = mac if addresses: args["addresses"] = address_list yield rdf_client_network.Interface(**args)
def _TestInterfaces(self, client_nr): ip1 = rdf_client_network.NetworkAddress() ip1.human_readable_address = "192.168.0.%d" % client_nr ip2 = rdf_client_network.NetworkAddress() ip2.human_readable_address = "2001:abcd::%x" % client_nr mac1 = rdf_client_network.MacAddress.FromHumanReadableAddress( "aabbccddee%02x" % client_nr) mac2 = rdf_client_network.MacAddress.FromHumanReadableAddress( "bbccddeeff%02x" % client_nr) return [ rdf_client_network.Interface(addresses=[ip1, ip2]), rdf_client_network.Interface(mac_address=mac1), rdf_client_network.Interface(mac_address=mac2), ]
def EnumerateInterfaces(self, _): self.response_count += 1 return [ rdf_client_network.Interface( mac_address=b"123456", addresses=[ rdf_client_network.NetworkAddress( human_readable_address="100.100.100.1"), ]) ]
def testIfaces(self): ifname = 'test_ifname' data_store.REL_DB.WriteClientMetadata( client_id=ClientTest.FAKE_CLIENT_ID, fleetspeak_enabled=False) client = rdf_objects.ClientSnapshot(client_id=ClientTest.FAKE_CLIENT_ID) client.interfaces = [rdf_client_network.Interface(ifname=ifname)] data_store.REL_DB.WriteClientSnapshot(client) client = grr_colab.Client.with_id(ClientTest.FAKE_CLIENT_ID) self.assertLen(client.ifaces, 1) self.assertEqual(client.ifaces[0].ifname, ifname)
def ParseIfaddrs(ifaddrs): """Parses contents of the intrusive linked list of `ifaddrs`. Args: ifaddrs: A pointer to the first node of `ifaddrs` linked list. Can be NULL. Returns: An iterator over instances of `rdf_client_network.Interface`. """ precondition.AssertOptionalType(ifaddrs, ctypes.POINTER(Ifaddrs)) ifaces = {} for ifaddr in IterIfaddrs(ifaddrs): ifname = ctypes.string_at(ifaddr.ifa_name).decode("utf-8") iface = ifaces.setdefault(ifname, rdf_client_network.Interface()) iface.ifname = ifname if not ifaddr.ifa_addr: continue sockaddr = ctypes.cast(ifaddr.ifa_addr, ctypes.POINTER(Sockaddr)) iffamily = sockaddr.contents.sa_family if iffamily == AF_INET: sockaddrin = ctypes.cast(ifaddr.ifa_addr, ctypes.POINTER(Sockaddrin)) address = rdf_client_network.NetworkAddress() address.address_type = rdf_client_network.NetworkAddress.Family.INET address.packed_bytes = struct.pack("=L", sockaddrin.contents.sin_addr) iface.addresses.append(address) elif iffamily == AF_INET6: sockaddrin = ctypes.cast(ifaddr.ifa_addr, ctypes.POINTER(Sockaddrin6)) address = rdf_client_network.NetworkAddress() address.address_type = rdf_client_network.NetworkAddress.Family.INET6 address.packed_bytes = bytes(list(sockaddrin.contents.sin6_addr)) iface.addresses.append(address) elif iffamily == AF_LINK: sockaddrdl = ctypes.cast(ifaddr.ifa_addr, ctypes.POINTER(Sockaddrdl)) nlen = sockaddrdl.contents.sdl_nlen alen = sockaddrdl.contents.sdl_alen iface.mac_address = bytes(sockaddrdl.contents.sdl_data[nlen:nlen + alen]) else: raise ValueError("Unexpected socket address family: %s" % iffamily) return itervalues(ifaces)
def EnumerateInterfaces(self, _): self.response_count += 1 return [ rdf_client_network.Interface( mac_address="123456", addresses=[ rdf_client_network.NetworkAddress( address_type=rdf_client_network.NetworkAddress.Family. INET, human_readable="100.100.100.1", packed_bytes=socket.inet_pton(socket.AF_INET, "100.100.100.1"), ) ]) ]
def testRepeatedFields(self): """Test handling of protobuf repeated fields.""" sample = rdf_client_network.Interface() # Add a simple string. sample.ip4_addresses.Append("127.0.0.1") self.assertEqual(sample.ip4_addresses[0], "127.0.0.1") # Add an invalid type. self.assertRaises(type_info.TypeValueError, sample.addresses.Append, 2) # Add a protobuf sample.addresses.Append(human_readable="127.0.0.1") self.assertEqual(sample.addresses[0].human_readable, "127.0.0.1") self.assertEqual(len(sample.addresses), 1)
def testRepeatedFields(self): """Test handling of protobuf repeated fields.""" sample = rdf_client_network.Interface() # Add an invalid type. self.assertRaises(type_info.TypeValueError, sample.addresses.Append, 2) # Add an rdfvalue by kwargs. sample.addresses.Append(human_readable_address="127.0.0.1") self.assertEqual(sample.addresses[0].human_readable_address, "127.0.0.1") self.assertLen(sample.addresses, 1) # Add an rdfvalue. sample.addresses.Append( rdf_client_network.NetworkAddress(human_readable_address="1.2.3.4")) self.assertLen(sample.addresses, 2) self.assertEqual(sample.addresses[1].human_readable_address, "1.2.3.4")
def Start(cls, args): del args # Unused. pythoncom.CoInitialize() for interface in wmi.WMI().Win32_NetworkAdapterConfiguration(): addresses = [] for ip_address in interface.IPAddress or []: addresses.append( rdf_client_network.NetworkAddress( human_readable_address=ip_address)) response = rdf_client_network.Interface( ifname=interface.Description) if interface.MACAddress: response.mac_address = binascii.unhexlify( interface.MACAddress.replace(":", "")) if addresses: response.addresses = addresses yield response
def _SetupClients(self, n): res = {} for i in range(1, n + 1): client_id = "C.100000000000000%d" % i client = rdf_objects.ClientSnapshot(client_id=client_id) client.knowledge_base.os = "Windows" client.knowledge_base.fqdn = "host-%d.example.com" % i ipv4_addr = rdf_client_network.NetworkAddress( address_type=rdf_client_network.NetworkAddress.Family.INET, packed_bytes=ipaddress.IPv4Address("192.168.0.%d" % i).packed) ipv6_addr = rdf_client_network.NetworkAddress( address_type=rdf_client_network.NetworkAddress.Family.INET6, packed_bytes=ipaddress.IPv6Address("2001:abcd::%d" % i).packed) client.interfaces = [ rdf_client_network.Interface( addresses=[ipv4_addr, ipv6_addr], mac_address=binascii.unhexlify("aabbccddee0%d" % i)) ] res[client_id] = client return res
def testMultiple(self): foo_ipv4 = socket.inet_pton(socket.AF_INET, "192.0.2.1") foo_mac = b"\x00\xa0\xc9\x14\xc8\x29" foo_sockaddrin = self.osx.Sockaddrin() foo_sockaddrin.sin_family = self.osx.AF_INET foo_sockaddrin.sin_addr = struct.unpack("=L", foo_ipv4)[0] foo_sockaddrdl = self.osx.Sockaddrdl() foo_sockaddrdl.sdl_family = self.osx.AF_LINK foo_sockaddrdl.sdl_data[0:len(foo_mac)] = list(bytes(foo_mac)) foo_sockaddrdl.sdl_nlen = 0 foo_sockaddrdl.sdl_alen = len(foo_mac) bar_ipv6 = socket.inet_pton(socket.AF_INET6, "2607:f0d0:1002:51::4") bar_mac = b"\x48\x2c\x6a\x1e\x59\x3d" bar_sockaddrin = self.osx.Sockaddrin6() bar_sockaddrin.sin6_family = self.osx.AF_INET6 bar_sockaddrin.sin6_addr = struct.unpack("=" + "B" * 16, bar_ipv6) bar_sockaddrdl = self.osx.Sockaddrdl() bar_sockaddrdl.sdl_family = self.osx.AF_LINK bar_sockaddrdl.sdl_data[0:len(foo_mac)] = list(bytes(bar_mac)) bar_sockaddrdl.sdl_nlen = 0 bar_sockaddrdl.sdl_alen = len(bar_mac) ifaddr = self.osx.Ifaddrs() ifaddr.ifa_next = None ifaddr.ifa_name = ctypes.create_string_buffer("foo") ifaddr.ifa_addr = ctypes.cast(ctypes.pointer(foo_sockaddrin), ctypes.POINTER(self.osx.Sockaddr)) ifnext = ifaddr ifaddr = self.osx.Ifaddrs() ifaddr.ifa_next = ctypes.pointer(ifnext) ifaddr.ifa_name = ctypes.create_string_buffer("foo") ifaddr.ifa_addr = ctypes.cast(ctypes.pointer(foo_sockaddrdl), ctypes.POINTER(self.osx.Sockaddr)) ifnext = ifaddr ifaddr = self.osx.Ifaddrs() ifaddr.ifa_next = ctypes.pointer(ifnext) ifaddr.ifa_name = ctypes.create_string_buffer("bar") ifaddr.ifa_addr = ctypes.cast(ctypes.pointer(bar_sockaddrdl), ctypes.POINTER(self.osx.Sockaddr)) ifnext = ifaddr ifaddr = self.osx.Ifaddrs() ifaddr.ifa_next = ctypes.pointer(ifnext) ifaddr.ifa_name = ctypes.create_string_buffer("bar") ifaddr.ifa_addr = ctypes.cast(ctypes.pointer(bar_sockaddrin), ctypes.POINTER(self.osx.Sockaddr)) expected_foo_iface = rdf_client_network.Interface( ifname="foo", mac_address=foo_mac, addresses=[ rdf_client_network.NetworkAddress( address_type=rdf_client_network.NetworkAddress.Family.INET, packed_bytes=foo_ipv4), ]) expected_bar_iface = rdf_client_network.Interface( ifname="bar", mac_address=bar_mac, addresses=[ rdf_client_network.NetworkAddress( address_type=rdf_client_network.NetworkAddress.Family. INET6, packed_bytes=bar_ipv6), ]) results = list(self.osx.ParseIfaddrs(ctypes.pointer(ifaddr))) self.assertSameElements(results, [expected_foo_iface, expected_bar_iface])
def testGetClientSummary(self): hostname = "test" system = "Linux" os_release = "12.02" kernel = "3.15-rc2" fqdn = "test.test.com" arch = "amd64" install_time = rdfvalue.RDFDatetime.Now() user = "******" userobj = rdf_client.User(username=user) interface = rdf_client_network.Interface(ifname="eth0") google_cloud_instance = rdf_cloud.GoogleCloudInstance( instance_id="1771384456894610289", zone="projects/123456789733/zones/us-central1-a", project_id="myproject", unique_id="us-central1-a/myproject/1771384456894610289") cloud_instance = rdf_cloud.CloudInstance(cloud_type="GOOGLE", google=google_cloud_instance) serial_number = "DSD33679FZ" system_manufacturer = "Foobar Inc." system_uuid = "C31292AD-6Z4F-55D8-28AC-EC1100E42222" hwinfo = rdf_client.HardwareInfo( serial_number=serial_number, system_manufacturer=system_manufacturer, system_uuid=system_uuid) timestamp = 1 with utils.Stubber(time, "time", lambda: timestamp): with aff4.FACTORY.Create("C.0000000000000000", aff4_grr.VFSGRRClient, mode="rw", token=self.token) as fd: kb = rdf_client.KnowledgeBase() kb.users.Append(userobj) empty_summary = fd.GetSummary() self.assertEqual(empty_summary.client_id, "C.0000000000000000") self.assertFalse(empty_summary.system_info.version) self.assertEqual(empty_summary.timestamp.AsSecondsSinceEpoch(), 1) # This will cause TYPE to be written with current time = 101 when the # object is closed timestamp += 100 fd.Set(fd.Schema.HOSTNAME(hostname)) fd.Set(fd.Schema.SYSTEM(system)) fd.Set(fd.Schema.OS_RELEASE(os_release)) fd.Set(fd.Schema.KERNEL(kernel)) fd.Set(fd.Schema.FQDN(fqdn)) fd.Set(fd.Schema.ARCH(arch)) fd.Set(fd.Schema.INSTALL_DATE(install_time)) fd.Set(fd.Schema.KNOWLEDGE_BASE(kb)) fd.Set(fd.Schema.USERNAMES(user)) fd.Set(fd.Schema.HARDWARE_INFO(hwinfo)) fd.Set(fd.Schema.INTERFACES([interface])) fd.Set(fd.Schema.CLOUD_INSTANCE(cloud_instance)) with aff4.FACTORY.Open("C.0000000000000000", aff4_grr.VFSGRRClient, mode="rw", token=self.token) as fd: summary = fd.GetSummary() self.assertEqual(summary.system_info.system, system) self.assertEqual(summary.system_info.release, os_release) self.assertEqual(summary.system_info.kernel, kernel) self.assertEqual(summary.system_info.fqdn, fqdn) self.assertEqual(summary.system_info.machine, arch) self.assertEqual(summary.system_info.install_date, install_time) self.assertItemsEqual(summary.users, [userobj]) self.assertItemsEqual(summary.interfaces, [interface]) self.assertFalse(summary.client_info) self.assertEqual(summary.timestamp.AsSecondsSinceEpoch(), 101) self.assertEqual(summary.cloud_type, "GOOGLE") self.assertEqual( summary.cloud_instance_id, "us-central1-a/myproject/1771384456894610289") self.assertEqual(summary.serial_number, serial_number) self.assertEqual(summary.system_manufacturer, system_manufacturer) self.assertEqual(summary.system_uuid, system_uuid)