shared_ptr<DnsClientResult>DnsLookupClient::LookupDiscoveryService(
  shared_ptr<Domain>domain)
{
  if (domain.get() == nullptr) {
    throw exceptions::RMSInvalidArgumentException("Invalid domain");
  }

  auto pResolver = IDnsServerResolver::Create();

  string domainString            = domain->GetDomainStringForDnsLookup();
  vector<string> possibleDomains = GetPossibleDomains(domainString);

  for (auto possibleDomainIt = begin(possibleDomains);
       possibleDomainIt != end(possibleDomains); ++possibleDomainIt)
  {
    Logger::Hidden("possibleDomain: %s", possibleDomainIt->c_str());
    string dnsRequest(RMS_QUERY_PREFIX + *possibleDomainIt);
    auto   dnsResponse = pResolver->lookup(dnsRequest);

    if (dnsResponse.empty())
    {
      Logger::Hidden("Failed DNS lookup with domain: %s",
                     possibleDomainIt->c_str());
      continue;
    }

    Logger::Hidden("Successfully queried results with domain: %s",
                   possibleDomainIt->c_str());
    return DnsClientResult::Create(dnsResponse);
  }

  return DnsClientResult::Create(string("api.aadrm.com"));
}
Beispiel #2
0
// use during setup, as this discards all incoming requests until it returns
bool EtherCard::dnsLookup (const char* name, bool fromRam) {
    word start = millis();

    while(!isLinkUp())
    {
        packetLoop(packetReceive());
        if ((word) (millis() - start) >= 30000)
            return false; //timeout waiting for link
    }
    start = millis();
    while(clientWaitingGw())
    {
        packetLoop(packetReceive());
        if ((word) (millis() - start) >= 30000)
            return false; //timeout waiting for gateway ARP
    }

    memset(hisip, 0, 4);
    dnsRequest(name, fromRam);

    start = millis();
    while (hisip[0] == 0) {
        if ((word) (millis() - start) >= 30000)
            return false; //timout waiting for dns response
        word len = packetReceive();
        if (len > 0 && packetLoop(len) == 0) //packet not handled by tcp/ip packet loop
            if(checkForDnsAnswer(len))
                return false; //DNS response recieved with error
    }

    return true;
}
Beispiel #3
0
bool RuleList::removeDomain(QString appName, QString domainName, unsigned int port)
{
	bool ret=true;

	QList<QString> ips=dnsRequest(domainName);
	for(int i=0;i<ips.size();i++)
		if(!removeRule(appName, ips[i], port))
			ret=false;

	return ret;
}
Beispiel #4
0
bool RuleList::addDomain(QString appName, QString domainName, unsigned int port)
{
	//If we forbid to add a domain
	if(maxDomainsPerApplication()==0)
		return false;

	//If we only one domain per app, then, delete the currently allowed domain
	if(rules[appName].size()>0 && maxDomainsPerApplication()==1)
		removeAppRules(appName);

	//Add the domain
	QList<QString> ips=dnsRequest(domainName);
	for(int i=0;i<ips.size();i++)
		addRule(appName, ips[i], port);

	return true;
}
Beispiel #5
0
// use during setup, as this discards all incoming requests until it returns
bool EtherCard::dnsLookup (prog_char* name, bool fromRam) {
  while (!isLinkUp() || clientWaitingGw())
    packetLoop(packetReceive());
    
  memset(hisip, 0, 4);
  dnsRequest(name, fromRam);

  word start = millis();
  while (hisip[0] == 0) {
    if ((word) (millis() - start) >= 30000)
      return false;
    word len = packetReceive();
    if (len > 0 && packetLoop(len) == 0)
      checkForDnsAnswer(len);
  }

  return true;
}
Beispiel #6
0
IPv4Address NetworkUtils::getIPv4Address(std::string hostname, PcapLiveDevice* device, double& dnsResponseTimeMS, uint32_t& dnsTTL,
		int dnsTimeout, IPv4Address dnsServerIP, IPv4Address gatewayIP)
{
	IPv4Address result = IPv4Address::Zero;

	// open the device if not already opened
	bool closeDeviceAtTheEnd = false;
	if (!device->isOpened())
	{
		closeDeviceAtTheEnd = true;
		if (!device->open())
		{
			LOG_ERROR("Cannot open device");
			return result;
		}
	}

	// first - resolve gateway MAC address

	// if gateway IP wasn't provided - try to find the default gateway
	if (gatewayIP == IPv4Address::Zero)
	{
		gatewayIP = device->getDefaultGateway();
	}

	if (!gatewayIP.isValid() || gatewayIP == IPv4Address::Zero)
	{
		LOG_ERROR("Gateway address isn't valid or couldn't find default gateway");
		return result;
	}

	// send the ARP request to find gateway MAC address
	double arpResTime;
	MacAddress gatewayMacAddress = getMacAddress(gatewayIP, device, arpResTime);

	if (gatewayMacAddress == MacAddress::Zero)
	{
		LOG_ERROR("Coulnd't resolve gateway MAC address");
		return result;
	}

	if (dnsTimeout <= 0)
		dnsTimeout = NetworkUtils::DefaultTimeout;

	// validate DNS server IP. If it wasn't provided - set the system-configured DNS server
	if (dnsServerIP == IPv4Address::Zero && device->getDnsServers().size() > 0)
	{
		dnsServerIP = device->getDnsServers().at(0);
	}

	if (!dnsServerIP.isValid())
	{
		LOG_ERROR("DNS server IP isn't valid");
		return result;
	}

	// create DNS request

	Packet dnsRequest(100);
	MacAddress sourceMac = device->getMacAddress();
	EthLayer ethLayer(sourceMac, gatewayMacAddress, PCPP_ETHERTYPE_IP);
	IPv4Layer ipLayer(device->getIPv4Address(), dnsServerIP);
	ipLayer.getIPv4Header()->timeToLive = 128;

	// randomize source port to a number >= 10000
	int srcPortLowest = 10000;
	int srcPortRange = (2^16) - srcPortLowest;
	uint16_t srcPort = (rand() % srcPortRange) + srcPortLowest;
	UdpLayer udpLayer(srcPort, DNS_PORT);

	// create the DNS request for the hostname
	DnsLayer dnsLayer;

	// randomize transaction ID
	uint16_t transactionID = rand() % (2^16);
	dnsLayer.getDnsHeader()->transactionID = htons(transactionID);
	dnsLayer.addQuery(hostname, DNS_TYPE_A, DNS_CLASS_IN);

	// add all layers to packet
	if (!dnsRequest.addLayer(&ethLayer) || !dnsRequest.addLayer(&ipLayer) || !dnsRequest.addLayer(&udpLayer) || !dnsRequest.addLayer(&dnsLayer))
	{
		LOG_ERROR("Couldn't construct DNS query");
		return result;
	}

	dnsRequest.computeCalculateFields();

	// set a DNS response filter on the device
	PortFilter dnsResponseFilter(53, SRC);
	if (!device->setFilter(dnsResponseFilter))
	{
		LOG_ERROR("Couldn't set DNS respnse filter");
		return result;
	}

	// since packet capture is done on another thread, I use a conditional mutex with timeout to synchronize between the capture
	// thread and the main thread. When the capture thread starts running the main thread is blocking on the conditional mutex.
	// When the DNS response are captured the capture thread signals the main thread and the main thread stops capturing and continues
	// to the next iteration. if a timeout passes and no DNS response is captured, the main thread stops capturing

	pthread_mutex_t mutex;
	pthread_cond_t cond;

	// init the conditonal mutex
	pthread_mutex_init(&mutex, 0);
	pthread_cond_init(&cond, 0);

	// this is the token that passes between the 2 threads
	DNSRecievedData data = {
			&mutex,
			&cond,
			hostname,
			transactionID,
			clock(),
			IPv4Address::Zero,
			0,
			0
	};


	struct timeval now;
	gettimeofday(&now,NULL);

	// create the timeout
	timespec timeout = {
			now.tv_sec + dnsTimeout,
			now.tv_usec
	};

	// start capturing. The capture is done on another thread, hence "dnsResponseRecieved" is running on that thread
	device->startCapture(dnsResponseRecieved, &data);

	// send the DNS request
	device->sendPacket(&dnsRequest);

	pthread_mutex_lock(&mutex);

	// block on the conditional mutex until capture thread signals or until timeout expires
	int res = pthread_cond_timedwait(&cond, &mutex, &timeout);

	// stop the capturing thread
	device->stopCapture();

	pthread_mutex_unlock(&mutex);

	// check if timeout expired
	if (res == ETIMEDOUT)
	{
		LOG_ERROR("DNS request time out");
		return result;
	}

	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond);

	if (closeDeviceAtTheEnd)
		device->close();
	else
		device->clearFilter();

	result = data.result;
	dnsResponseTimeMS = data.dnsResponseTime;
	dnsTTL = data.ttl;

	return result;
}