|
reSIProcate/stack
9694
|
00001 #if !defined(RESIP_HELPER_HXX) 00002 #define RESIP_HELPER_HXX 00003 00004 #include <time.h> 00005 00006 #include "resip/stack/NonceHelper.hxx" 00007 #include "resip/stack/Symbols.hxx" 00008 #include "resip/stack/Uri.hxx" 00009 #include "resip/stack/MethodTypes.hxx" 00010 #include "rutil/BaseException.hxx" 00011 #include "rutil/Data.hxx" 00012 #include "resip/stack/Contents.hxx" 00013 #include "resip/stack/SecurityAttributes.hxx" 00014 #include "resip/stack/SdpContents.hxx" 00015 00016 namespace resip 00017 { 00018 00019 class SipMessage; 00020 class NameAddr; 00021 class SecurityAttributes; 00022 class Security; 00023 00024 class UnsupportedAuthenticationScheme : public BaseException 00025 { 00026 public: 00027 UnsupportedAuthenticationScheme(const Data& msg, const Data& file, const int line) 00028 : BaseException(msg, file, line) {} 00029 00030 const char* name() const { return "UnsupportedAuthenticationScheme"; } 00031 }; 00032 00033 00043 class Helper 00044 { 00045 public: 00046 00048 const static int tagSize; 00049 00058 template<typename T> 00059 static T aBitSmallerThan(T secs) 00060 { 00061 return resipMax(T(0), resipMin(T(secs-5), T(9*secs/10))); 00062 } 00063 00078 static void integer2hex(char* _d, unsigned int _s, bool _l = true); 00079 00089 static unsigned int hex2integer(const char* _s); 00090 00105 static int jitterValue(int input, int lowerPercentage, int upperPercentage, int minimum=0); 00106 00115 static SipMessage* makeInvite(const NameAddr& target, const NameAddr& from); 00116 00128 static SipMessage* makeInvite(const NameAddr& target, const NameAddr& from, const NameAddr& contact); 00129 00150 static void makeResponse(SipMessage& response, 00151 const SipMessage& request, 00152 int responseCode, 00153 const Data& reason = Data::Empty, 00154 const Data& hostname = Data::Empty, 00155 const Data& warning=Data::Empty); 00156 00179 static void makeResponse(SipMessage& response, 00180 const SipMessage& request, 00181 int responseCode, 00182 const NameAddr& myContact, 00183 const Data& reason = Data::Empty, 00184 const Data& hostname = Data::Empty, 00185 const Data& warning=Data::Empty); 00186 00209 static SipMessage* makeResponse(const SipMessage& request, 00210 int responseCode, 00211 const Data& reason = Data::Empty, 00212 const Data& hostname = Data::Empty, 00213 const Data& warning=Data::Empty); 00214 00239 static SipMessage* makeResponse(const SipMessage& request, 00240 int responseCode, 00241 const NameAddr& myContact, 00242 const Data& reason = Data::Empty, 00243 const Data& hostname = Data::Empty, 00244 const Data& warning=Data::Empty); 00245 00246 static void makeRawResponse(Data& rawBuffer, 00247 const SipMessage& request, 00248 int responseCode, 00249 const Data& additionalHeaders=Data::Empty, 00250 const Data& body=Data::Empty); 00251 00271 static SipMessage* make405(const SipMessage& request, 00272 const int* allowedMethods = 0, 00273 int nMethods = -1); 00274 00283 static void getResponseCodeReason(int responseCode, Data& reason); 00284 00307 static SipMessage* makeRequest(const NameAddr& target, const NameAddr& from, const NameAddr& contact, MethodTypes method); 00308 00326 static SipMessage* makeRequest(const NameAddr& target, const NameAddr& from, MethodTypes method); 00327 00336 static SipMessage* makeCancel(const SipMessage& request); 00337 00339 static SipMessage* makeRegister(const NameAddr& to, const NameAddr& from, const NameAddr& contact); 00340 00342 static SipMessage* makeRegister(const NameAddr& to, const NameAddr& from); 00343 00345 static SipMessage* makeRegister(const NameAddr& to, const Data& transport, const NameAddr& contact); 00346 00348 static SipMessage* makeRegister(const NameAddr& to, const Data& transport); 00349 00351 static SipMessage* makeSubscribe(const NameAddr& target, const NameAddr& from, const NameAddr& contact); 00352 00354 static SipMessage* makeSubscribe(const NameAddr& target, const NameAddr& from); 00355 00357 static SipMessage* makeMessage(const NameAddr& target, const NameAddr& from, const NameAddr& contact); 00358 00360 static SipMessage* makeMessage(const NameAddr& target, const NameAddr& from); 00361 00363 static SipMessage* makePublish(const NameAddr& target, const NameAddr& from, const NameAddr& contact); 00364 00366 static SipMessage* makePublish(const NameAddr& target, const NameAddr& from); 00367 00383 static SipMessage* makeFailureAck(const SipMessage& request, const SipMessage& response); 00384 00391 static Data computeUniqueBranch(); 00392 static Data computeProxyBranch(const SipMessage& request); 00393 00394 static Data computeCallId(); 00395 static Data computeTag(int numBytes); 00396 00397 enum AuthResult {Failed = 1, Authenticated, Expired, BadlyFormed}; 00398 00399 static AuthResult authenticateRequest(const SipMessage& request, 00400 const Data& realm, 00401 const Data& password, 00402 int expiresDelta = 0); 00403 00404 static AuthResult authenticateRequestWithA1(const SipMessage& request, 00405 const Data& realm, 00406 const Data& hA1, 00407 int expiresDelta = 0); 00408 00409 static std::pair<AuthResult,Data> 00410 advancedAuthenticateRequest(const SipMessage& request, 00411 const Data& realm, 00412 const Data& a1, 00413 int expiresDelta = 0, 00414 bool proxyAuthorization = true); 00415 00416 // create a 407 response with Proxy-Authenticate header filled in 00417 static SipMessage* makeProxyChallenge(const SipMessage& request, 00418 const Data& realm, 00419 bool useAuth = true, 00420 bool stale = false); 00421 00422 //create a 401 response with WWW-Authenticate header filled in 00423 static SipMessage* makeWWWChallenge(const SipMessage& request, 00424 const Data& realm, 00425 bool useAuth = true, 00426 bool stale = false); 00427 00428 // create a 401 or 407 response with Proxy-Authenticate or Authenticate header 00429 // filled in 00430 static SipMessage* makeChallenge(const SipMessage& request, 00431 const Data& realm, 00432 bool useAuth = true, 00433 bool stale = false, 00434 bool proxy = false); 00435 00436 static Data qopOption(const Auth& challenge); 00437 static void updateNonceCount(unsigned int& nonceCount, Data& nonceCountString); 00438 static bool algorithmAndQopSupported(const Auth& challenge); 00439 00440 00441 // adds authorization headers in reponse to the 401 or 407--currently 00442 // only supports md5. 00443 static SipMessage& addAuthorization(SipMessage& request, 00444 const SipMessage& challenge, 00445 const Data& username, 00446 const Data& password, 00447 const Data& cnonce, 00448 unsigned int& nonceCount); 00449 00450 static Auth makeChallengeResponseAuth(const SipMessage& request, 00451 const Data& username, 00452 const Data& password, 00453 const Auth& challenge, 00454 const Data& cnonce, 00455 unsigned int& nonceCount, 00456 Data& nonceCountString); 00457 00458 static void makeChallengeResponseAuth(const SipMessage& request, 00459 const Data& username, 00460 const Data& password, 00461 const Auth& challenge, 00462 const Data& cnonce, 00463 const Data& authQop, 00464 const Data& nonceCountString, 00465 Auth& auth); 00466 00467 static Auth makeChallengeResponseAuthWithA1(const SipMessage& request, 00468 const Data& username, 00469 const Data& passwordHashA1, 00470 const Auth& challenge, 00471 const Data& cnonce, 00472 unsigned int& nonceCount, 00473 Data& nonceCountString); 00474 00475 static void makeChallengeResponseAuthWithA1(const SipMessage& request, 00476 const Data& username, 00477 const Data& passwordHashA1, 00478 const Auth& challenge, 00479 const Data& cnonce, 00480 const Data& authQop, 00481 const Data& nonceCountString, 00482 Auth& auth); 00483 00484 static Data makeResponseMD5WithA1(const Data& a1, 00485 const Data& method, const Data& digestUri, const Data& nonce, 00486 const Data& qop = Data::Empty, const Data& cnonce = Data::Empty, 00487 const Data& cnonceCount = Data::Empty, const Contents *entityBody = 0); 00488 00489 static Data makeResponseMD5(const Data& username, const Data& password, const Data& realm, 00490 const Data& method, const Data& digestUri, const Data& nonce, 00491 const Data& qop = Data::Empty, const Data& cnonce = Data::Empty, 00492 const Data& cnonceCount = Data::Empty, const Contents *entityBody = 0); 00493 00495 static void setNonceHelper(NonceHelper *nonceHelper); 00496 static NonceHelper* getNonceHelper(); 00497 static Data makeNonce(const SipMessage& request, const Data& timestamp); 00498 00499 static Uri makeUri(const Data& aor, const Data& scheme=Symbols::DefaultSipScheme); 00500 00501 static void processStrictRoute(SipMessage& request); 00502 00503 // return the port that the response should be sent to using rules from 00504 // RFC 3261 - 18.2.2 00505 static int getPortForReply(SipMessage& request); 00506 00507 static void massageRoute(const SipMessage& request, NameAddr& route); 00508 00509 static Uri fromAor(const Data& aor, const Data& scheme=Symbols::DefaultSipScheme); 00510 00511 // Do basic checks to validate a received message off the wire 00512 // If the basic check fails, and reason is non-null, reason will be set 00513 // to the reason the check failed. This function does not take ownership 00514 // of reason. 00515 static bool validateMessage(const SipMessage& message,resip::Data* reason=0); 00516 00517 // GRUU support -- reversibly and opaquely combine instance id and aor 00518 static Data gruuUserPart(const Data& instanceId, 00519 const Data& aor, 00520 const Data& key); 00521 00522 // GRUU support -- extract instance id and aor from user portion 00523 static std::pair<Data,Data> fromGruuUserPart(const Data& gruuUserPart, 00524 const Data& key); 00525 00526 struct ContentsSecAttrs 00527 { 00528 ContentsSecAttrs(); 00529 ContentsSecAttrs(std::auto_ptr<Contents> contents, 00530 std::auto_ptr<SecurityAttributes> attributes); 00531 ContentsSecAttrs(const ContentsSecAttrs& rhs); 00532 ContentsSecAttrs& operator=(const ContentsSecAttrs& rhs); 00533 mutable std::auto_ptr<Contents> mContents; 00534 mutable std::auto_ptr<SecurityAttributes> mAttributes; 00535 }; 00536 00537 static ContentsSecAttrs extractFromPkcs7(const SipMessage& message, Security& security); 00538 00539 00540 enum FailureMessageEffect{ DialogTermination, TransactionTermination, UsageTermination, 00541 RetryAfter, OptionalRetryAfter, ApplicationDependant }; 00542 00543 static FailureMessageEffect determineFailureMessageEffect(const SipMessage& response); 00544 00545 // Just simply walk the contents tree and return the first SdpContents in 00546 // the tree. 00547 static std::auto_ptr<SdpContents> getSdp(Contents* tree); 00548 00561 static bool isClientBehindNAT(const SipMessage& request, bool privateToPublicOnly=true); 00562 00571 static Tuple getClientPublicAddress(const SipMessage& request); 00572 00573 private: 00574 class NonceHelperPtr 00575 { 00576 public: 00577 NonceHelperPtr() : mNonceHelper(0) {} 00578 ~NonceHelperPtr() { delete mNonceHelper; } 00579 NonceHelper *mNonceHelper; 00580 }; 00581 static NonceHelperPtr mNonceHelperPtr; 00582 }; 00583 00584 } 00585 00586 #endif 00587 00588 /* ==================================================================== 00589 * The Vovida Software License, Version 1.0 00590 * 00591 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00592 * 00593 * Redistribution and use in source and binary forms, with or without 00594 * modification, are permitted provided that the following conditions 00595 * are met: 00596 * 00597 * 1. Redistributions of source code must retain the above copyright 00598 * notice, this list of conditions and the following disclaimer. 00599 * 00600 * 2. Redistributions in binary form must reproduce the above copyright 00601 * notice, this list of conditions and the following disclaimer in 00602 * the documentation and/or other materials provided with the 00603 * distribution. 00604 * 00605 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00606 * and "Vovida Open Communication Application Library (VOCAL)" must 00607 * not be used to endorse or promote products derived from this 00608 * software without prior written permission. For written 00609 * permission, please contact vocal@vovida.org. 00610 * 00611 * 4. Products derived from this software may not be called "VOCAL", nor 00612 * may "VOCAL" appear in their name, without prior written 00613 * permission of Vovida Networks, Inc. 00614 * 00615 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00616 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00617 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00618 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00619 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00620 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00621 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00622 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00623 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00624 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00625 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00626 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00627 * DAMAGE. 00628 * 00629 * ==================================================================== 00630 * 00631 * This software consists of voluntary contributions made by Vovida 00632 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00633 * Inc. For more information on Vovida Networks, Inc., please see 00634 * <http://www.vovida.org/>. 00635 * 00636 */
1.7.5.1