reSIProcate/repro  9694
Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes
repro::AclStore Class Reference

#include <AclStore.hxx>

Collaboration diagram for repro::AclStore:
Collaboration graph
[legend]

List of all members.

Classes

class  AddressRecord
class  TlsPeerNameRecord

Public Types

typedef resip::Data Key
typedef std::vector
< TlsPeerNameRecord
TlsPeerNameList
typedef std::vector
< AddressRecord
AddressList

Public Member Functions

 AclStore (AbstractDb &db)
 ~AclStore ()
bool addAcl (const resip::Data &tlsPeerName, const resip::Data &address, const short &mask, const short &port, const short &family, const short &transport)
bool addAcl (const resip::Data &tlsPeerNameOrAddress, const short &port, const short &transport)
void eraseAcl (const resip::Data &key)
resip::Data getTlsPeerName (const resip::Data &key)
resip::Tuple getAddressTuple (const resip::Data &key)
short getAddressMask (const resip::Data &key)
Key getFirstTlsPeerNameKey ()
Key getNextTlsPeerNameKey (Key &key)
Key getFirstAddressKey ()
Key getNextAddressKey (Key &key)
bool isTlsPeerNameTrusted (const std::list< resip::Data > &tlsPeerNames)
bool isAddressTrusted (const resip::Tuple &address)
bool isRequestTrusted (const resip::SipMessage &request)

Private Member Functions

Key buildKey (const resip::Data &tlsPeerName, const resip::Data &address, const short &mask, const short &port, const short &family, const short &transport) const
bool findTlsPeerNameKey (const Key &key)
bool findAddressKey (const Key &key)

Private Attributes

AbstractDbmDb
resip::RWMutex mMutex
TlsPeerNameList mTlsPeerNameList
TlsPeerNameList::iterator mTlsPeerNameCursor
AddressList mAddressList
AddressList::iterator mAddressCursor

Detailed Description

Definition at line 13 of file AclStore.hxx.


Member Typedef Documentation

Definition at line 34 of file AclStore.hxx.

Definition at line 32 of file AclStore.hxx.

Definition at line 33 of file AclStore.hxx.


Constructor & Destructor Documentation

AclStore::AclStore ( AbstractDb db)

Definition at line 29 of file AclStore.cxx.

                                :
   mDb(db)
{  
   AbstractDb::Key key = mDb.firstAclKey();
   while ( !key.empty() )
   {
      AbstractDb::AclRecord rec = mDb.getAcl(key);
      if(rec.mTlsPeerName.empty())  // If there is no TlsPeerName then record is an Address ACL
      {
         AddressRecord addressRecord(rec.mAddress, rec.mPort, (resip::TransportType)rec.mTransport);
         addressRecord.mMask = rec.mMask;
         addressRecord.key = buildKey(Data::Empty, rec.mAddress, rec.mMask, rec.mPort, rec.mFamily, rec.mTransport);
         mAddressList.push_back(addressRecord);
      }
      else
      {
         TlsPeerNameRecord tlsPeerNameRecord;
         tlsPeerNameRecord.mTlsPeerName = rec.mTlsPeerName;
         tlsPeerNameRecord.key = buildKey(rec.mTlsPeerName, Data::Empty, 0, 0, 0, 0);
         mTlsPeerNameList.push_back(tlsPeerNameRecord); 
      }
      key = mDb.nextAclKey();
   } 
   mTlsPeerNameCursor = mTlsPeerNameList.begin();
   mAddressCursor = mAddressList.begin();
}
AclStore::~AclStore ( )

Definition at line 57 of file AclStore.cxx.

{
}

Member Function Documentation

bool AclStore::addAcl ( const resip::Data tlsPeerName,
const resip::Data address,
const short &  mask,
const short &  port,
const short &  family,
const short &  transport 
)

Definition at line 63 of file AclStore.cxx.

{ 
   Data key = buildKey(tlsPeerName, address, mask, port, family, transport);
   InfoLog( << "Add ACL: key=" << key);
   
   AbstractDb::AclRecord rec;
   rec.mTlsPeerName = tlsPeerName;
   rec.mAddress = address;
   rec.mMask = mask;
   rec.mPort = port;
   rec.mFamily = family;
   rec.mTransport = transport;

   // Add DB record
   if(!mDb.addAcl(key, rec))
   {
      return false;
   }

   // Add local storage
   if(rec.mTlsPeerName.empty())  // If there is no TlsPeerName then record is an Address ACL
   {
      AddressRecord addressRecord(rec.mAddress, rec.mPort, (resip::TransportType)rec.mTransport);
      addressRecord.mMask = rec.mMask;
      addressRecord.key = buildKey(Data::Empty, rec.mAddress, rec.mMask, rec.mPort, rec.mFamily, rec.mTransport);
      {
         WriteLock lock(mMutex);
         mAddressList.push_back(addressRecord);
      }
   }
   else
   {
      TlsPeerNameRecord tlsPeerNameRecord;
      tlsPeerNameRecord.mTlsPeerName = rec.mTlsPeerName;
      tlsPeerNameRecord.key = buildKey(rec.mTlsPeerName, Data::Empty, 0, 0, 0, 0);
      {
         WriteLock lock(mMutex);
         mTlsPeerNameList.push_back(tlsPeerNameRecord); 
      }
   }
   return true;
}
bool AclStore::addAcl ( const resip::Data tlsPeerNameOrAddress,
const short &  port,
const short &  transport 
)

Definition at line 113 of file AclStore.cxx.

{
   // Input can be in any of these formats
   // localhost         localhost  (becomes 127.0.0.1/8, ::1/128 and fe80::1/64)
   // bare hostname     server1
   // FQDN              server1.example.com
   // IPv4 address      192.168.1.100
   // IPv4 + mask       192.168.1.0/24
   // IPv6 address      :341:0:23:4bb:0011:2435:abcd
   // IPv6 + mask       :341:0:23:4bb:0011:2435:abcd/80
   // IPv6 reference    [:341:0:23:4bb:0011:2435:abcd]
   // IPv6 ref + mask   [:341:0:23:4bb:0011:2435:abcd]/64

   try
   {
      ParseBuffer pb(tlsPeerNameOrAddress);
      const char* anchor = pb.start();

      bool ipv4 = false;
      bool ipv6 = false;
      Data hostOrIp;
      //u_char in[28];
      struct in_addr in4;
#ifdef USE_IPV6
      struct in6_addr in6;
#endif
      int mask;

      if (*pb.position() == '[')   // encountered beginning of IPv6 reference
      {
         anchor = pb.skipChar();
         pb.skipToEndQuote(']');

         pb.data(hostOrIp, anchor);  // copy the presentation form of the IPv6 address
         anchor = pb.skipChar();

         // try to convert into IPv6 network form
#ifdef USE_IPV6
         if (!DnsUtil::inet_pton( hostOrIp.c_str(), in6)) 
#endif
         {
            return false;
         }
         ipv6 = true;
      }
      else
      {
         pb.skipToOneOf(".:");
         if (pb.position() == pb.end())   // We probably have a bare hostname
         {
            pb.data(hostOrIp, anchor);
            if (hostOrIp.lowercase() == "localhost")
            {
               // add special localhost addresses for v4 and v6 to list and return
               addAcl(Data::Empty, "127.0.0.1", 8, port, resip::V4, transport);
               addAcl(Data::Empty, "::1", 128, port, resip::V6, transport);
               return addAcl(Data::Empty, "fe80::1", 64, port, resip::V6, transport);
            }
            else
            {
               // hostOrIp += default domain name (future)
               return addAcl(hostOrIp, Data::Empty, 0, 0, 0, 0);
            }
         }
         else if (*pb.position() == ':')     // Must be an IPv6 address
         {
            pb.skipToChar('/');
            pb.data(hostOrIp, anchor);  // copy the presentation form of the IPv6 address

            // try to convert into IPv6 network form
#ifdef USE_IPV6
            if (!DnsUtil::inet_pton( hostOrIp.c_str(), in6)) 
#endif
            {
               return false;
            }
            ipv6 = true;
         }
         else // *pb.position() == '.'
         {
            // Could be either an IPv4 address or an FQDN
            pb.skipToChar('/');
            pb.data(hostOrIp, anchor);  // copy the presentation form of the address

            // try to interpret as an IPv4 address, if that fails look it up in DNS
            if (DnsUtil::inet_pton( hostOrIp.c_str(), in4)) 
            {
               // it was an IPv4 address
               ipv4 = true;
            }
            else
            {
               // hopefully it is a legal FQDN, try it.
               return addAcl(hostOrIp, Data::Empty, 0, 0, 0, 0);
            }
         }   
      }

      if (!pb.eof() && *pb.position() == '/')    // grab the mask as well
      {
         anchor = pb.skipChar();
         mask = pb.integer();

         if (ipv4)
         {
            if (mask < 8 || mask > 32)
            {
               return false;
            }
         }
         else if (ipv6)
         {
            if (mask < 64 || mask > 128)
            {
               return false;
            }
         }
      }
      else
      {
         if (ipv4)
         {
            mask = 32;
         }
         else // ipv6
         {
            mask = 128;
         }
      }

      if(pb.eof())
      {
         bool ret;
         if (ipv6)
         {
            ret = addAcl(Data::Empty, hostOrIp, mask, port, resip::V6, transport);
         }

         if (ipv4)
         {
            ret = addAcl(Data::Empty, hostOrIp, mask, port, resip::V4, transport);
         }
         return ret;
      }      
   }
   catch(ParseException& e)
   {
      ErrLog(<< "Exception caught:" << e);
   }
   return false;
}
AbstractDb::Key AclStore::buildKey ( const resip::Data tlsPeerName,
const resip::Data address,
const short &  mask,
const short &  port,
const short &  family,
const short &  transport 
) const [private]

Definition at line 295 of file AclStore.cxx.

{  
   Data pKey = tlsPeerName+":"+address+"/"+Data(mask)+":"+Data(port)+":"+Data(family)+":"+Data(transport); 
   return pKey;
}
void AclStore::eraseAcl ( const resip::Data key)

Definition at line 269 of file AclStore.cxx.

{  
   // Erase DB record
   mDb.eraseAcl( key );

   // Erase local storage
   if(key.prefix(":"))  // a key that starts with a : has no peer name - thus a Address key
   {
      WriteLock lock(mMutex);
      if(findAddressKey(key))
      {
         mAddressList.erase(mAddressCursor);
      }
   }
   else
   {
      WriteLock lock(mMutex);
      if(findTlsPeerNameKey(key))
      {
         mTlsPeerNameCursor = mTlsPeerNameList.erase(mTlsPeerNameCursor);
      }
   }
}
bool AclStore::findAddressKey ( const Key key) [private]

Definition at line 382 of file AclStore.cxx.

{ 
   // check if cursor happens to be at the key
   if ( mAddressCursor != mAddressList.end() )
   {
      if ( mAddressCursor->key == key )
      {
         return true;
      }
   }
   
   // search for the key 
   mAddressCursor = mAddressList.begin();
   while (  mAddressCursor != mAddressList.end() )
   {
      if ( mAddressCursor->key == key )
      {
         return true; // found the key 
      }
      mAddressCursor++;
   }
   return false; // key was not found 
}
bool AclStore::findTlsPeerNameKey ( const Key key) [private]

Definition at line 322 of file AclStore.cxx.

{ 
   // check if cursor happens to be at the key
   if ( mTlsPeerNameCursor != mTlsPeerNameList.end() )
   {
      if ( mTlsPeerNameCursor->key == key )
      {
         return true;
      }
   }
   
   // search for the key 
   mTlsPeerNameCursor = mTlsPeerNameList.begin();
   while (  mTlsPeerNameCursor != mTlsPeerNameList.end() )
   {
      if ( mTlsPeerNameCursor->key == key )
      {
         return true; // found the key 
      }
      mTlsPeerNameCursor++;
   }
   return false; // key was not found 
}
short AclStore::getAddressMask ( const resip::Data key)

Definition at line 452 of file AclStore.cxx.

{
   ReadLock lock(mMutex);
   if ( !findAddressKey(key) )
   {
      return 0;
   }
   return mAddressCursor->mMask;
}
resip::Tuple AclStore::getAddressTuple ( const resip::Data key)

Definition at line 440 of file AclStore.cxx.

{
   ReadLock lock(mMutex);
   if ( !findAddressKey(key) )
   {
      return Tuple();
   }
   return mAddressCursor->mAddressTuple;
}
AclStore::Key AclStore::getFirstAddressKey ( )

Definition at line 368 of file AclStore.cxx.

{
   ReadLock lock(mMutex);
   mAddressCursor = mAddressList.begin();
   if ( mAddressCursor == mAddressList.end() )
   {
      return Key( Data::Empty );
   }
   
   return mAddressCursor->key;
}
AclStore::Key AclStore::getFirstTlsPeerNameKey ( )

Definition at line 308 of file AclStore.cxx.

{
   ReadLock lock(mMutex);
   mTlsPeerNameCursor = mTlsPeerNameList.begin();
   if ( mTlsPeerNameCursor == mTlsPeerNameList.end() )
   {
      return Key( Data::Empty );
   }
   
   return mTlsPeerNameCursor->key;
}
AclStore::Key AclStore::getNextAddressKey ( Key key)

Definition at line 408 of file AclStore.cxx.

{  
   ReadLock lock(mMutex);
   if ( !findAddressKey(key) )
   {
      return Key(Data::Empty);
   }
      
   mAddressCursor++;
   
   if ( mAddressCursor == mAddressList.end() )
   {
      return Key( Data::Empty );
   }
   
   return mAddressCursor->key;
}
AclStore::Key AclStore::getNextTlsPeerNameKey ( Key key)

Definition at line 348 of file AclStore.cxx.

{  
   ReadLock lock(mMutex);
   if ( !findTlsPeerNameKey(key) )
   {
      return Key(Data::Empty);
   }
      
   mTlsPeerNameCursor++;
   
   if ( mTlsPeerNameCursor == mTlsPeerNameList.end() )
   {
      return Key( Data::Empty );
   }
   
   return mTlsPeerNameCursor->key;
}
resip::Data AclStore::getTlsPeerName ( const resip::Data key)

Definition at line 428 of file AclStore.cxx.

{
   ReadLock lock(mMutex);
   if ( !findTlsPeerNameKey(key) )
   {
      return Data::Empty;
   }
   return mTlsPeerNameCursor->mTlsPeerName;
}
bool AclStore::isAddressTrusted ( const resip::Tuple address)

Definition at line 483 of file AclStore.cxx.

{
   ReadLock lock(mMutex);
   for(AddressList::iterator i = mAddressList.begin(); i != mAddressList.end(); i++)
   {
      if(i->mAddressTuple.isEqualWithMask(address, i->mMask, i->mAddressTuple.getPort() == 0))
      {
         return true;
      }
   }
   return false;
}
bool AclStore::isRequestTrusted ( const resip::SipMessage request)

Definition at line 499 of file AclStore.cxx.

{
   bool trusted = false;
   Tuple source = request.getSource();
   
   // check if the request came over a secure channel and sucessfully authenticated 
   // (ex: TLS or DTLS)
   const Data& receivedTransport = request.header(h_Vias).front().transport();
#ifdef USE_SSL
   if(receivedTransport == Symbols::TLS
#ifdef USE_DTLS
      || receivedTransport == Symbols::DTLS
#endif
      )
   {
      const std::list<Data>& tlsPeerNames = request.getTlsPeerNames();
      if(!tlsPeerNames.empty() && isTlsPeerNameTrusted(tlsPeerNames))
      {
         trusted = true;
      }
   }
#endif

   // check the source address against the TrustedNode list
   if(!trusted)
   {
      if(isAddressTrusted(source))
      {
         InfoLog (<< "AclStore - source address IS trusted: " << source.presentationFormat() << ":" << source.getPort() << " " << Tuple::toData(source.getType()));
         trusted = true;
      }
      else
      {
         InfoLog (<< "AclStore - source address NOT trusted: " << source.presentationFormat() << ":" << source.getPort() << " " << Tuple::toData(source.getType()));
      }
   }      
      
   return trusted;
}
bool AclStore::isTlsPeerNameTrusted ( const std::list< resip::Data > &  tlsPeerNames)

Definition at line 464 of file AclStore.cxx.

{
   ReadLock lock(mMutex);
   for(std::list<Data>::const_iterator it = tlsPeerNames.begin(); it != tlsPeerNames.end(); it++)
   {
      for(TlsPeerNameList::iterator i = mTlsPeerNameList.begin(); i != mTlsPeerNameList.end(); i++)
      {
         if(isEqualNoCase(i->mTlsPeerName, *it))
         {
            InfoLog (<< "AclStore - Tls peer name IS trusted: " << *it);
            return true;
         }
      }
   }
   return false;
}

Member Data Documentation

AddressList::iterator repro::AclStore::mAddressCursor [private]

Definition at line 83 of file AclStore.hxx.

Definition at line 82 of file AclStore.hxx.

Definition at line 67 of file AclStore.hxx.

Definition at line 79 of file AclStore.hxx.

TlsPeerNameList::iterator repro::AclStore::mTlsPeerNameCursor [private]

Definition at line 81 of file AclStore.hxx.

Definition at line 80 of file AclStore.hxx.


The documentation for this class was generated from the following files: