예제 #1
0
bool AccessControl::isBannedAddress(const boost::asio::ip::address& source)
{
  if (!_enabled)
    return false;
  
  bool banned = false;
  _packetCounterMutex.lock();

  if (_banLifeTime > 0)
  {
    boost::posix_time::ptime now(boost::posix_time::microsec_clock::local_time());
    std::vector<boost::asio::ip::address> parole;
    for (std::map<boost::asio::ip::address, boost::posix_time::ptime>::iterator iter = _banned.begin();
      iter != _banned.end(); iter++)
    {
      boost::posix_time::time_duration timeDiff = now - iter->second;
      if (timeDiff.total_milliseconds() >  _banLifeTime * 1000)
        parole.push_back(iter->first);
    }

    for (std::vector<boost::asio::ip::address>::iterator iter = parole.begin(); iter != parole.end(); iter++)
    {
      if (_autoNullRoute)
      {
        delNullRoute(*iter);
      }
      _banned.erase(*iter);
    }
  }

  if (isWhiteListed(source))
  {
    banned = false;
  }
  else
  {
    if (_denyAllIncoming)
    {
      banned = true;
    }
    else
    {
      banned = _banned.find(source) != _banned.end();
    }
    
    if (!banned)
    {
      banned = isBlackListed(source);
    }
    
  }
  _packetCounterMutex.unlock();
  
  if (banned && _autoNullRoute)
  {
    addNullRoute(source);
  }

  return banned;
}
예제 #2
0
SnippetRuleBase::Rules SnippetRuleBase::
lookup(Uri const& uri, StringRange const siteKey/*= {}*/) const
{
    Rules result;

    if (isWhiteListed(uri, siteKey)) return result;

    if (!isDomainSpecificOnly(uri, siteKey)) {
        result = m_genericRules;
    }

    std::copy_if(
        m_specificRules.begin(), m_specificRules.end(),
        std::back_inserter(result),
        [&](auto* rule) { return rule->match(uri); }
    );

    return result;
}
예제 #3
0
void AccessControl::logPacket(const boost::asio::ip::address& source, std::size_t bytesRead, ViolationReport* pReport)
{
   /****************************************************************************
    * The packet rate ratio allows the transport to detect a potential DoS     *
    * attack.  It works by detecting the packet read rate per second as        *
    * designated by the upper limit.  If the value of packet rate is 50/100,   *
    * the maximum packet rate before the SBC raises the alert level if a       *
    * potential denial of service attack is 100 packets per second.            *
    * When this happens, the transport layer checks if there is a particular   *
    * IP that is sending more than its allowable rate of 50 packets per second.*
    * If the sender is violating the threshold, it will be banned for 1 hour   *
    * which is the third parameter of 3600 seconds.                            *
    ****************************************************************************/
  
  if (!_enabled)
    return;
  _packetCounterMutex.lock();

  std::map<boost::asio::ip::address, unsigned int>::iterator iter = _packetCounter.find(source);
  if (iter != _packetCounter.end())
    _packetCounter[source] = ++iter->second;
  else
    _packetCounter[source] = 1;

  if (++_currentIterationCount >= _packetsPerSecondThreshold)
  {
    boost::posix_time::ptime now(boost::posix_time::microsec_clock::local_time());
    int currentCount = _currentIterationCount;
    _currentIterationCount = 0;
    boost::posix_time::time_duration timeDiff = now - _lastTime;
    if (timeDiff.total_milliseconds() <=  1000)
    {
      //
      // We got a ratelimit violation
      //
      OSS_LOG_WARNING("ALERT: Threshold Violation Detected.  Rate " << currentCount << " >= " << _packetsPerSecondThreshold);

      if (pReport)
        pReport->thresholdViolated = true;
      
      std::size_t watermark = 0;
      boost::asio::ip::address suspect;
      for (std::map<boost::asio::ip::address, unsigned int>::iterator iter = _packetCounter.begin();
        iter != _packetCounter.end(); iter++)
      {
        if (iter->second > watermark)
        {
          watermark = iter->second;
          suspect = iter->first;
          
          if (watermark >= _thresholdViolationRate && _autoBanThresholdViolators )
          {
            if (!isWhiteListed(suspect))
            {
              OSS_LOG_WARNING("ALERT: Threshold Violator Address = " << suspect.to_string() <<
                " Packets sent within the last second is " << watermark
                << ". Violator is now in jail for a maximum of " << _banLifeTime << " seconds.");
              banAddress(suspect);
              
              if (pReport)
                pReport->violators.push_back(suspect.to_string());
            }
            else
            {
              OSS_LOG_WARNING("ALERT: Threshold Violator Address = " << suspect.to_string() <<
                " Packets sent within the last second is " << watermark
                << ". Violator is TRUSTED and will be allowed to bombard.");
            }
          }
          else if (watermark >= _thresholdViolationRate && !_autoBanThresholdViolators )
          {
            OSS_LOG_WARNING("ALERT: Threshold Violator Address = " << suspect.to_string() <<
                " Packets sent within the last second is " << watermark
                << ". Automatic ban is disabled.  Allowing this IP to bombard.");
          }
        }
      }     
    }
    //
    // Reset
    //
    _packetCounter.clear();
    _lastTime = now;
  }


  _packetCounterMutex.unlock();
}
예제 #4
0
void enforcePolicy(unsigned long threadID, ostream& os)
{
    TAStack oStack;
    TACallInfo info;
    TAHashPair hashPair;
    
    bool firstEntry;
    bool oStackHasSourceClass = false;
    bool hashCalculated = false;
    
    string objectAddress;
    string str1="", str2="";
    size_t hash1, hash2;
    
    oStack = threadStacks[threadID];
    objectAddress = oStack.top().first;
    info = oStack.top().second;
    
    firstEntry = true;
    
    //check if the frame on top of stack represents message to/using a whitelisted class/method
    if (isWhiteListed(info))
        return;
    
    for(map<unsigned long, TAStack>::iterator it = threadStacks.begin(); it!= threadStacks.end(); ++it)
    {
        //skip own stack
        if ((*it).first == threadID)
            continue;
        
        TAStack tStack = (*it).second;
        
        //Potential access violation
        if (tStack.top().first == objectAddress)
        {
            TACallInfo info2 = tStack.top().second;
            
            //if whitelisted, continue to next thread
            if (isWhiteListed(info2))
                continue;
            
            /*
             compute the hash for oStack and check if it has source class exactly once per call to this function.
             
             rather than performing this step outside the for loop (to execute it exactly once), we perform this
             step here because for about 75-80% input we will satisfy both "if" conditions above. this means that 
             we would unnecessarily comput hash1 and make a call to hasSourceClass(oStack) if the step is performed
             outside the loop (or earlier than here).
             
             Note: Compiler optimizations in place too.
             -OFast results in a difficult to debug code since the code doesn't stop at breakpoints properly, and
             step-in/step-over results in a difficult to follow execution order -> different from the order in
             which the program is written.
             
            */
            if (!hashCalculated)
            {
                //compute hash for this stack
                hash1 = getHashForStack(oStack);
                //check if this stack has any frame where the class name is one of the classes defined in the source (not a OS class)
                oStackHasSourceClass = hasSourceClass(oStack);
                hashCalculated = true;
            }
            
            //check if the stack(trace) contains a frame where the class name is one of the classes defined in the source (not a OS class)
            if (!oStackHasSourceClass && !hasSourceClass(tStack))
                continue;
            
            //Check for duplication now:
            //first compute hash for the stack
            hash2 = getHashForStack(tStack);
            
            //then find if the hash pair exists
            hashPair = make_pair(hash1, hash2);
            
            if (hashPairs.find(hashPair) == hashPairs.end())
            {
                //this is a new pair
                hashPairs.insert(hashPair);
                
                //Now create a new row for this frame in the output file.
                //If this is the first row for a violation on this object address
                if (firstEntry)
                {
                    os<<"<tr>"<<"<td width='70'>#"<<objectAddress<<"</td><td width='70'>"<<info.tid<<"*"<<"</td><td width='750'>$"<<info.className<<":"<<info.methodName<<" ("<<info.stackDepth<<")"<<"</td><td>";
                    
                    printStackTrace(oStack, os, info.stackDepth);
                    
                    os<<"</td></tr>";
                    firstEntry = false;
                }
                
                //create row for the other frame
                os<<"<tr>"<<"<td width='70'>"<<" "<<"</td><td width='70'>"<<info2.tid<<"</td><td width='750'>$"<<info2.className<<":"<<info2.methodName<<" ("<<info2.stackDepth<<")"<<"</td><td>";
                
                printStackTrace(tStack, os, info2.stackDepth);
                
                os<<"</td></tr>";
                
                //add these class to the set of violating classes
                violatingClasses.insert(info.className);
                violatingClasses.insert(info2.className);
            }
        }
    }
}