|
reSIProcate/repro
9694
|
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 */
1.7.5.1