reSIProcate/repro  9694
AclStore.cxx
Go to the documentation of this file.
00001 
00002 #if defined(HAVE_CONFIG_H)
00003   #include "config.h"
00004 #endif
00005 
00006 #include "rutil/Socket.hxx"
00007 #include "rutil/Logger.hxx"
00008 #include "rutil/ParseBuffer.hxx"
00009 #include "rutil/DnsUtil.hxx"
00010 #include "rutil/Lock.hxx"
00011 #include "resip/stack/Uri.hxx"
00012 #include "resip/stack/ConnectionManager.hxx"
00013 #include "resip/stack/SipMessage.hxx"
00014 
00015 #include "repro/AclStore.hxx"
00016 
00017 #ifdef USE_SSL
00018 #include "resip/stack/ssl/TlsConnection.hxx"
00019 #include "resip/stack/ssl/TlsTransport.hxx"
00020 #endif
00021 
00022 using namespace resip;
00023 using namespace repro;
00024 using namespace std;
00025 
00026 
00027 #define RESIPROCATE_SUBSYSTEM Subsystem::REPRO
00028 
00029 AclStore::AclStore(AbstractDb& db):
00030    mDb(db)
00031 {  
00032    AbstractDb::Key key = mDb.firstAclKey();
00033    while ( !key.empty() )
00034    {
00035       AbstractDb::AclRecord rec = mDb.getAcl(key);
00036       if(rec.mTlsPeerName.empty())  // If there is no TlsPeerName then record is an Address ACL
00037       {
00038          AddressRecord addressRecord(rec.mAddress, rec.mPort, (resip::TransportType)rec.mTransport);
00039          addressRecord.mMask = rec.mMask;
00040          addressRecord.key = buildKey(Data::Empty, rec.mAddress, rec.mMask, rec.mPort, rec.mFamily, rec.mTransport);
00041          mAddressList.push_back(addressRecord);
00042       }
00043       else
00044       {
00045          TlsPeerNameRecord tlsPeerNameRecord;
00046          tlsPeerNameRecord.mTlsPeerName = rec.mTlsPeerName;
00047          tlsPeerNameRecord.key = buildKey(rec.mTlsPeerName, Data::Empty, 0, 0, 0, 0);
00048          mTlsPeerNameList.push_back(tlsPeerNameRecord); 
00049       }
00050       key = mDb.nextAclKey();
00051    } 
00052    mTlsPeerNameCursor = mTlsPeerNameList.begin();
00053    mAddressCursor = mAddressList.begin();
00054 }
00055 
00056 
00057 AclStore::~AclStore()
00058 {
00059 }
00060 
00061 
00062 bool
00063 AclStore::addAcl(const resip::Data& tlsPeerName,
00064                   const resip::Data& address,
00065                   const short& mask,
00066                   const short& port,
00067                   const short& family,
00068                   const short& transport)
00069 { 
00070    Data key = buildKey(tlsPeerName, address, mask, port, family, transport);
00071    InfoLog( << "Add ACL: key=" << key);
00072    
00073    AbstractDb::AclRecord rec;
00074    rec.mTlsPeerName = tlsPeerName;
00075    rec.mAddress = address;
00076    rec.mMask = mask;
00077    rec.mPort = port;
00078    rec.mFamily = family;
00079    rec.mTransport = transport;
00080 
00081    // Add DB record
00082    if(!mDb.addAcl(key, rec))
00083    {
00084       return false;
00085    }
00086 
00087    // Add local storage
00088    if(rec.mTlsPeerName.empty())  // If there is no TlsPeerName then record is an Address ACL
00089    {
00090       AddressRecord addressRecord(rec.mAddress, rec.mPort, (resip::TransportType)rec.mTransport);
00091       addressRecord.mMask = rec.mMask;
00092       addressRecord.key = buildKey(Data::Empty, rec.mAddress, rec.mMask, rec.mPort, rec.mFamily, rec.mTransport);
00093       {
00094          WriteLock lock(mMutex);
00095          mAddressList.push_back(addressRecord);
00096       }
00097    }
00098    else
00099    {
00100       TlsPeerNameRecord tlsPeerNameRecord;
00101       tlsPeerNameRecord.mTlsPeerName = rec.mTlsPeerName;
00102       tlsPeerNameRecord.key = buildKey(rec.mTlsPeerName, Data::Empty, 0, 0, 0, 0);
00103       {
00104          WriteLock lock(mMutex);
00105          mTlsPeerNameList.push_back(tlsPeerNameRecord); 
00106       }
00107    }
00108    return true;
00109 }
00110 
00111 
00112 bool 
00113 AclStore::addAcl(const resip::Data& tlsPeerNameOrAddress,
00114                   const short& port,
00115                   const short& transport)
00116 {
00117    // Input can be in any of these formats
00118    // localhost         localhost  (becomes 127.0.0.1/8, ::1/128 and fe80::1/64)
00119    // bare hostname     server1
00120    // FQDN              server1.example.com
00121    // IPv4 address      192.168.1.100
00122    // IPv4 + mask       192.168.1.0/24
00123    // IPv6 address      :341:0:23:4bb:0011:2435:abcd
00124    // IPv6 + mask       :341:0:23:4bb:0011:2435:abcd/80
00125    // IPv6 reference    [:341:0:23:4bb:0011:2435:abcd]
00126    // IPv6 ref + mask   [:341:0:23:4bb:0011:2435:abcd]/64
00127 
00128    try
00129    {
00130       ParseBuffer pb(tlsPeerNameOrAddress);
00131       const char* anchor = pb.start();
00132 
00133       bool ipv4 = false;
00134       bool ipv6 = false;
00135       Data hostOrIp;
00136       //u_char in[28];
00137       struct in_addr in4;
00138 #ifdef USE_IPV6
00139       struct in6_addr in6;
00140 #endif
00141       int mask;
00142 
00143       if (*pb.position() == '[')   // encountered beginning of IPv6 reference
00144       {
00145          anchor = pb.skipChar();
00146          pb.skipToEndQuote(']');
00147 
00148          pb.data(hostOrIp, anchor);  // copy the presentation form of the IPv6 address
00149          anchor = pb.skipChar();
00150 
00151          // try to convert into IPv6 network form
00152 #ifdef USE_IPV6
00153          if (!DnsUtil::inet_pton( hostOrIp.c_str(), in6)) 
00154 #endif
00155          {
00156             return false;
00157          }
00158          ipv6 = true;
00159       }
00160       else
00161       {
00162          pb.skipToOneOf(".:");
00163          if (pb.position() == pb.end())   // We probably have a bare hostname
00164          {
00165             pb.data(hostOrIp, anchor);
00166             if (hostOrIp.lowercase() == "localhost")
00167             {
00168                // add special localhost addresses for v4 and v6 to list and return
00169                addAcl(Data::Empty, "127.0.0.1", 8, port, resip::V4, transport);
00170                addAcl(Data::Empty, "::1", 128, port, resip::V6, transport);
00171                return addAcl(Data::Empty, "fe80::1", 64, port, resip::V6, transport);
00172             }
00173             else
00174             {
00175                // hostOrIp += default domain name (future)
00176                return addAcl(hostOrIp, Data::Empty, 0, 0, 0, 0);
00177             }
00178          }
00179          else if (*pb.position() == ':')     // Must be an IPv6 address
00180          {
00181             pb.skipToChar('/');
00182             pb.data(hostOrIp, anchor);  // copy the presentation form of the IPv6 address
00183 
00184             // try to convert into IPv6 network form
00185 #ifdef USE_IPV6
00186             if (!DnsUtil::inet_pton( hostOrIp.c_str(), in6)) 
00187 #endif
00188             {
00189                return false;
00190             }
00191             ipv6 = true;
00192          }
00193          else // *pb.position() == '.'
00194          {
00195             // Could be either an IPv4 address or an FQDN
00196             pb.skipToChar('/');
00197             pb.data(hostOrIp, anchor);  // copy the presentation form of the address
00198 
00199             // try to interpret as an IPv4 address, if that fails look it up in DNS
00200             if (DnsUtil::inet_pton( hostOrIp.c_str(), in4)) 
00201             {
00202                // it was an IPv4 address
00203                ipv4 = true;
00204             }
00205             else
00206             {
00207                // hopefully it is a legal FQDN, try it.
00208                return addAcl(hostOrIp, Data::Empty, 0, 0, 0, 0);
00209             }
00210          }   
00211       }
00212 
00213       if (!pb.eof() && *pb.position() == '/')    // grab the mask as well
00214       {
00215          anchor = pb.skipChar();
00216          mask = pb.integer();
00217 
00218          if (ipv4)
00219          {
00220             if (mask < 8 || mask > 32)
00221             {
00222                return false;
00223             }
00224          }
00225          else if (ipv6)
00226          {
00227             if (mask < 64 || mask > 128)
00228             {
00229                return false;
00230             }
00231          }
00232       }
00233       else
00234       {
00235          if (ipv4)
00236          {
00237             mask = 32;
00238          }
00239          else // ipv6
00240          {
00241             mask = 128;
00242          }
00243       }
00244 
00245       if(pb.eof())
00246       {
00247          bool ret;
00248          if (ipv6)
00249          {
00250             ret = addAcl(Data::Empty, hostOrIp, mask, port, resip::V6, transport);
00251          }
00252 
00253          if (ipv4)
00254          {
00255             ret = addAcl(Data::Empty, hostOrIp, mask, port, resip::V4, transport);
00256          }
00257          return ret;
00258       }      
00259    }
00260    catch(ParseException& e)
00261    {
00262       ErrLog(<< "Exception caught:" << e);
00263    }
00264    return false;
00265 }
00266 
00267 
00268 void 
00269 AclStore::eraseAcl(const resip::Data& key)
00270 {  
00271    // Erase DB record
00272    mDb.eraseAcl( key );
00273 
00274    // Erase local storage
00275    if(key.prefix(":"))  // a key that starts with a : has no peer name - thus a Address key
00276    {
00277       WriteLock lock(mMutex);
00278       if(findAddressKey(key))
00279       {
00280          mAddressList.erase(mAddressCursor);
00281       }
00282    }
00283    else
00284    {
00285       WriteLock lock(mMutex);
00286       if(findTlsPeerNameKey(key))
00287       {
00288          mTlsPeerNameCursor = mTlsPeerNameList.erase(mTlsPeerNameCursor);
00289       }
00290    }
00291 }
00292 
00293 
00294 AbstractDb::Key 
00295 AclStore::buildKey(const resip::Data& tlsPeerName,
00296                      const resip::Data& address,
00297                      const short& mask,
00298                      const short& port,
00299                      const short& family,
00300                      const short& transport) const
00301 {  
00302    Data pKey = tlsPeerName+":"+address+"/"+Data(mask)+":"+Data(port)+":"+Data(family)+":"+Data(transport); 
00303    return pKey;
00304 }
00305 
00306 
00307 AclStore::Key 
00308 AclStore::getFirstTlsPeerNameKey()
00309 {
00310    ReadLock lock(mMutex);
00311    mTlsPeerNameCursor = mTlsPeerNameList.begin();
00312    if ( mTlsPeerNameCursor == mTlsPeerNameList.end() )
00313    {
00314       return Key( Data::Empty );
00315    }
00316    
00317    return mTlsPeerNameCursor->key;
00318 }
00319 
00320 
00321 bool 
00322 AclStore::findTlsPeerNameKey(const Key& key)
00323 { 
00324    // check if cursor happens to be at the key
00325    if ( mTlsPeerNameCursor != mTlsPeerNameList.end() )
00326    {
00327       if ( mTlsPeerNameCursor->key == key )
00328       {
00329          return true;
00330       }
00331    }
00332    
00333    // search for the key 
00334    mTlsPeerNameCursor = mTlsPeerNameList.begin();
00335    while (  mTlsPeerNameCursor != mTlsPeerNameList.end() )
00336    {
00337       if ( mTlsPeerNameCursor->key == key )
00338       {
00339          return true; // found the key 
00340       }
00341       mTlsPeerNameCursor++;
00342    }
00343    return false; // key was not found 
00344 }
00345 
00346 
00347 AclStore::Key 
00348 AclStore::getNextTlsPeerNameKey(Key& key)
00349 {  
00350    ReadLock lock(mMutex);
00351    if ( !findTlsPeerNameKey(key) )
00352    {
00353       return Key(Data::Empty);
00354    }
00355       
00356    mTlsPeerNameCursor++;
00357    
00358    if ( mTlsPeerNameCursor == mTlsPeerNameList.end() )
00359    {
00360       return Key( Data::Empty );
00361    }
00362    
00363    return mTlsPeerNameCursor->key;
00364 }
00365 
00366 
00367 AclStore::Key 
00368 AclStore::getFirstAddressKey()
00369 {
00370    ReadLock lock(mMutex);
00371    mAddressCursor = mAddressList.begin();
00372    if ( mAddressCursor == mAddressList.end() )
00373    {
00374       return Key( Data::Empty );
00375    }
00376    
00377    return mAddressCursor->key;
00378 }
00379 
00380 
00381 bool 
00382 AclStore::findAddressKey(const Key& key)
00383 { 
00384    // check if cursor happens to be at the key
00385    if ( mAddressCursor != mAddressList.end() )
00386    {
00387       if ( mAddressCursor->key == key )
00388       {
00389          return true;
00390       }
00391    }
00392    
00393    // search for the key 
00394    mAddressCursor = mAddressList.begin();
00395    while (  mAddressCursor != mAddressList.end() )
00396    {
00397       if ( mAddressCursor->key == key )
00398       {
00399          return true; // found the key 
00400       }
00401       mAddressCursor++;
00402    }
00403    return false; // key was not found 
00404 }
00405 
00406 
00407 AclStore::Key 
00408 AclStore::getNextAddressKey(Key& key)
00409 {  
00410    ReadLock lock(mMutex);
00411    if ( !findAddressKey(key) )
00412    {
00413       return Key(Data::Empty);
00414    }
00415       
00416    mAddressCursor++;
00417    
00418    if ( mAddressCursor == mAddressList.end() )
00419    {
00420       return Key( Data::Empty );
00421    }
00422    
00423    return mAddressCursor->key;
00424 }
00425 
00426 
00427 resip::Data 
00428 AclStore::getTlsPeerName( const resip::Data& key )
00429 {
00430    ReadLock lock(mMutex);
00431    if ( !findTlsPeerNameKey(key) )
00432    {
00433       return Data::Empty;
00434    }
00435    return mTlsPeerNameCursor->mTlsPeerName;
00436 }
00437 
00438 
00439 resip::Tuple 
00440 AclStore::getAddressTuple( const resip::Data& key )
00441 {
00442    ReadLock lock(mMutex);
00443    if ( !findAddressKey(key) )
00444    {
00445       return Tuple();
00446    }
00447    return mAddressCursor->mAddressTuple;
00448 }
00449  
00450 
00451 short 
00452 AclStore::getAddressMask( const resip::Data& key )
00453 {
00454    ReadLock lock(mMutex);
00455    if ( !findAddressKey(key) )
00456    {
00457       return 0;
00458    }
00459    return mAddressCursor->mMask;
00460 }
00461 
00462       
00463 bool 
00464 AclStore::isTlsPeerNameTrusted(const std::list<Data>& tlsPeerNames)
00465 {
00466    ReadLock lock(mMutex);
00467    for(std::list<Data>::const_iterator it = tlsPeerNames.begin(); it != tlsPeerNames.end(); it++)
00468    {
00469       for(TlsPeerNameList::iterator i = mTlsPeerNameList.begin(); i != mTlsPeerNameList.end(); i++)
00470       {
00471          if(isEqualNoCase(i->mTlsPeerName, *it))
00472          {
00473             InfoLog (<< "AclStore - Tls peer name IS trusted: " << *it);
00474             return true;
00475          }
00476       }
00477    }
00478    return false;
00479 }
00480  
00481 
00482 bool 
00483 AclStore::isAddressTrusted(const Tuple& address)
00484 {
00485    ReadLock lock(mMutex);
00486    for(AddressList::iterator i = mAddressList.begin(); i != mAddressList.end(); i++)
00487    {
00488       if(i->mAddressTuple.isEqualWithMask(address, i->mMask, i->mAddressTuple.getPort() == 0))
00489       {
00490          return true;
00491       }
00492    }
00493    return false;
00494 }
00495 
00496 
00497 // check the sender of the message via source IP address or identity from TLS 
00498 bool
00499 AclStore::isRequestTrusted(const SipMessage& request)
00500 {
00501    bool trusted = false;
00502    Tuple source = request.getSource();
00503    
00504    // check if the request came over a secure channel and sucessfully authenticated 
00505    // (ex: TLS or DTLS)
00506    const Data& receivedTransport = request.header(h_Vias).front().transport();
00507 #ifdef USE_SSL
00508    if(receivedTransport == Symbols::TLS
00509 #ifdef USE_DTLS
00510       || receivedTransport == Symbols::DTLS
00511 #endif
00512       )
00513    {
00514       const std::list<Data>& tlsPeerNames = request.getTlsPeerNames();
00515       if(!tlsPeerNames.empty() && isTlsPeerNameTrusted(tlsPeerNames))
00516       {
00517          trusted = true;
00518       }
00519    }
00520 #endif
00521 
00522    // check the source address against the TrustedNode list
00523    if(!trusted)
00524    {
00525       if(isAddressTrusted(source))
00526       {
00527          InfoLog (<< "AclStore - source address IS trusted: " << source.presentationFormat() << ":" << source.getPort() << " " << Tuple::toData(source.getType()));
00528          trusted = true;
00529       }
00530       else
00531       {
00532          InfoLog (<< "AclStore - source address NOT trusted: " << source.presentationFormat() << ":" << source.getPort() << " " << Tuple::toData(source.getType()));
00533       }
00534    }      
00535       
00536    return trusted;
00537 }
00538 
00539 
00540 /* ====================================================================
00541  * The Vovida Software License, Version 1.0 
00542  * 
00543  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00544  * 
00545  * Redistribution and use in source and binary forms, with or without
00546  * modification, are permitted provided that the following conditions
00547  * are met:
00548  * 
00549  * 1. Redistributions of source code must retain the above copyright
00550  *    notice, this list of conditions and the following disclaimer.
00551  * 
00552  * 2. Redistributions in binary form must reproduce the above copyright
00553  *    notice, this list of conditions and the following disclaimer in
00554  *    the documentation and/or other materials provided with the
00555  *    distribution.
00556  * 
00557  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00558  *    and "Vovida Open Communication Application Library (VOCAL)" must
00559  *    not be used to endorse or promote products derived from this
00560  *    software without prior written permission. For written
00561  *    permission, please contact vocal@vovida.org.
00562  *
00563  * 4. Products derived from this software may not be called "VOCAL", nor
00564  *    may "VOCAL" appear in their name, without prior written
00565  *    permission of Vovida Networks, Inc.
00566  * 
00567  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00568  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00569  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00570  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00571  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00572  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00573  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00574  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00575  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00576  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00577  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00578  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00579  * DAMAGE.
00580  * 
00581  * ====================================================================
00582  */