From d33e351f2081d96959e15389a6424d5c3ddbb734 Mon Sep 17 00:00:00 2001 From: Alexandre Savard Date: Thu, 28 Jan 2010 14:38:54 -0500 Subject: [PATCH] [#2522] Fix SDES negotiation to be compatible with incomplete key parameter field --- sflphone-common/src/sip/Pattern.cpp | 33 +++++++++++------ sflphone-common/src/sip/Pattern.h | 6 ++-- sflphone-common/src/sip/SdesNegotiator.cpp | 31 ++++------------ sflphone-common/test/sdesnegotiatorTest.cpp | 40 +++++++++++++++++---- sflphone-common/test/sdesnegotiatorTest.h | 11 +++--- 5 files changed, 71 insertions(+), 50 deletions(-) diff --git a/sflphone-common/src/sip/Pattern.cpp b/sflphone-common/src/sip/Pattern.cpp index 290c9f7a7..f925c8db9 100644 --- a/sflphone-common/src/sip/Pattern.cpp +++ b/sflphone-common/src/sip/Pattern.cpp @@ -25,9 +25,9 @@ namespace sfl Pattern::Pattern (const std::string& pattern, const std::string& options) : _pattern (pattern), + _re (NULL), _ovector (NULL), _ovectorSize (0), - _re (NULL), _count (0), _options (0) { @@ -139,8 +139,6 @@ std::string Pattern::group (int groupNumber) { const char * stringPtr; - // printf("_subject.substr : %s\n", _subject.substr (_offset[0]).c_str()); - int rc = pcre_get_substring ( _subject.substr (_offset[0]).c_str(), _ovector, @@ -180,12 +178,13 @@ std::string Pattern::group (const std::string& groupName) _count, groupName.c_str(), &stringPtr); - + if (rc < 0) { switch (rc) { case PCRE_ERROR_NOSUBSTRING: - throw std::out_of_range ("Invalid group reference."); + + break; case PCRE_ERROR_NOMEMORY: throw match_error ("Memory exhausted."); @@ -195,14 +194,23 @@ std::string Pattern::group (const std::string& groupName) } } - std::string matchedStr (stringPtr); + std::string matchedStr; - pcre_free_substring (stringPtr); + if(stringPtr) { + + matchedStr = stringPtr; + pcre_free_substring (stringPtr); + } + else { + + matchedStr = ""; + } return matchedStr; + } -size_t Pattern::start (const std::string& groupName) const +void Pattern::start (const std::string& groupName) const { int index = pcre_get_stringnumber (_re, groupName.c_str()); start (index); @@ -210,7 +218,7 @@ size_t Pattern::start (const std::string& groupName) const size_t Pattern::start (unsigned int groupNumber) const { - if (groupNumber <= _count) { + if (groupNumber <= (unsigned int)_count) { return _ovector[ (groupNumber + 1) * 2]; } else { throw std::out_of_range ("Invalid group reference."); @@ -222,7 +230,7 @@ size_t Pattern::start (void) const return _ovector[0] + _offset[0]; } -size_t Pattern::end (const std::string& groupName) const +void Pattern::end (const std::string& groupName) const { int index = pcre_get_stringnumber (_re, groupName.c_str()); end (index); @@ -230,7 +238,7 @@ size_t Pattern::end (const std::string& groupName) const size_t Pattern::end (unsigned int groupNumber) const { - if (groupNumber <= _count) { + if (groupNumber <= (unsigned int)_count) { return _ovector[ ( (groupNumber + 1) * 2) + 1 ] - 1; } else { throw std::out_of_range ("Invalid group reference."); @@ -249,6 +257,7 @@ bool Pattern::matches (void) throw (match_error) bool Pattern::matches (const std::string& subject) throw (match_error) { + // Try to find a match for this pattern int rc = pcre_exec ( _re, @@ -260,6 +269,8 @@ bool Pattern::matches (const std::string& subject) throw (match_error) _ovector, _ovectorSize); + + // Matching failed. if (rc < 0) { _offset[0] = _offset[1] = 0; diff --git a/sflphone-common/src/sip/Pattern.h b/sflphone-common/src/sip/Pattern.h index b07c92acd..870ca1b5e 100644 --- a/sflphone-common/src/sip/Pattern.h +++ b/sflphone-common/src/sip/Pattern.h @@ -143,10 +143,8 @@ namespace sfl { * Get the start position of the specified match. * * @param groupName The capturing group name. - * - * @return the start position of the specified match. */ - size_t start(const std::string& groupName) const; + void start(const std::string& groupName) const; /** * Get the end position of the overall match. @@ -171,7 +169,7 @@ namespace sfl { * * @return the end position of the specified match. */ - size_t end(const std::string& groupName) const; + void end(const std::string& groupName) const; /** * Get the number of capturing groups in the diff --git a/sflphone-common/src/sip/SdesNegotiator.cpp b/sflphone-common/src/sip/SdesNegotiator.cpp index 45ca512f6..ef2849bb7 100644 --- a/sflphone-common/src/sip/SdesNegotiator.cpp +++ b/sflphone-common/src/sip/SdesNegotiator.cpp @@ -65,23 +65,12 @@ std::vector SdesNegotiator::parse (void) "F8_128_HMAC_SHA1_80|" \ "[A-Za-z0-9_]+)"); // srtp-crypto-suite-ext - keyParamsPattern = new Pattern ( - "(?Pinline|[A-Za-z0-9_]+)\\:" \ - "(?P[A-Za-z0-9\x2B\x2F\x3D]+)\\|" \ - "(?:2\\^(?P[0-9]+)\\|" \ - "(?P[0-9]+)\\:" \ - "(?P[0-9]{1,3})\\;?)?","g"); - - // "(?Pinline|[A-Za-z0-9_]+)\\:(?P[A-Za-z0-9\x2B\x2F\x3D]+)\\|(?:2\\^(?P[0-9]+)\\|(?P[0-9]+)\\:(?P[0-9]{1,3})\\;?)?" - - /* keyParamsPattern = new Pattern ( - "(?Pinline|[A-Za-z0-9_]+)\\:" \ - "(?P[A-Za-z0-9\x2B\x2F\x3D]+)\\|" \ - "2\\^(?P[0-9]+)\\|" \ - "(?P[0-9]+)\\:" \ - "(?P[0-9]{1,3})\\;?", "g"); - */ + "(?Pinline|[A-Za-z0-9_]+)\\:" \ + "(?P[A-Za-z0-9\x2B\x2F\x3D]+)" \ + "(\\|2\\^(?P[0-9]+)\\|" \ + "(?P[0-9]+)\\:" \ + "(?P[0-9]{1,3})\\;?)?", "g"); sessionParamPattern = new Pattern ( "(?P(kdr\\=[0-9]{1,2}|" \ @@ -150,7 +139,7 @@ std::vector SdesNegotiator::parse (void) if (cryptoSuitePattern->matches()) { try { // std::cout << "Parsing the crypto suite field"; - cryptoSuite = cryptoSuitePattern->group ("cryptoSuite"); + cryptoSuite = cryptoSuitePattern->group ("cryptoSuite"); // std::cout << ": " << cryptoSuite << std::endl; } catch (match_error& exception) { throw parse_error ("Error while parsing the crypto-suite field"); @@ -169,18 +158,12 @@ std::vector SdesNegotiator::parse (void) std::string mkiValue; try { - while (keyParamsPattern->matches()) { - // std::cout << "Parsing the key parameters: " << std::endl; + while(keyParamsPattern->matches()) { srtpKeyMethod = keyParamsPattern->group ("srtpKeyMethod"); - // std::cout << " method: "<< srtpKeyMethod << std::endl; srtpKeyInfo = keyParamsPattern->group ("srtpKeyInfo"); - // std::cout << " info: "<< srtpKeyInfo << std::endl; lifetime = keyParamsPattern->group ("lifetime"); - // std::cout << " lifetime: "<< lifetime << std::endl; mkiValue = keyParamsPattern->group ("mkiValue"); - // std::cout << " mkiValue: "<< mkiValue << std::endl; mkiLength = keyParamsPattern->group ("mkiLength"); - // std::cout << " mkiLength: "<< mkiLength << std::endl; } } catch (match_error& exception) { throw parse_error ("Error while parsing the key-params field"); diff --git a/sflphone-common/test/sdesnegotiatorTest.cpp b/sflphone-common/test/sdesnegotiatorTest.cpp index b963fccc5..c7c709f4e 100644 --- a/sflphone-common/test/sdesnegotiatorTest.cpp +++ b/sflphone-common/test/sdesnegotiatorTest.cpp @@ -89,19 +89,46 @@ void SdesNegotiatorTest::testKeyParamsPattern() pattern = new sfl::Pattern("(?Pinline|[A-Za-z0-9_]+)\\:" \ "(?P[A-Za-z0-9\x2B\x2F\x3D]+)\\|" \ - "2\\^(?P[0-9]+)\\|" \ + "(2\\^(?P[0-9]+)\\|" \ "(?P[0-9]+)\\:" \ - "(?P[0-9]{1,3})\\;?", "g"); + "(?P[0-9]{1,3})\\;?)?", "g"); *pattern << subject; pattern->matches(); CPPUNIT_ASSERT(pattern->group("srtpKeyMethod").compare("inline:")); + CPPUNIT_ASSERT(pattern->group("srtpKeyInfo").compare("d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj") +== 0); + CPPUNIT_ASSERT(pattern->group("lifetime").compare("20")== 0); + CPPUNIT_ASSERT(pattern->group("mkiValue").compare("1")== 0); + CPPUNIT_ASSERT(pattern->group("mkiLength").compare("32")== 0); delete pattern; pattern = NULL; } +void SdesNegotiatorTest::testKeyParamsPatternWithoutMKI() +{ + + std::string subject = "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj"; + + pattern = new sfl::Pattern("(?Pinline|[A-Za-z0-9_]+)\\:" \ + "(?P[A-Za-z0-9\x2B\x2F\x3D]+)" \ + "(\\|2\\^(?P[0-9]+)\\|" \ + "(?P[0-9]+)\\:" \ + "(?P[0-9]{1,3})\\;?)?", "g"); + + *pattern << subject; + pattern->matches(); + CPPUNIT_ASSERT(pattern->group("srtpKeyMethod").compare("inline:")); + CPPUNIT_ASSERT(pattern->group("srtpKeyInfo").compare("d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj") +== 0); + + delete pattern; + pattern = NULL; +} + + /** * Make sure that all the fields can be extracted * properly from the syntax. @@ -179,15 +206,14 @@ void SdesNegotiatorTest::testMostSimpleCase() sfl::SdesNegotiator * negotiator = new sfl::SdesNegotiator(*capabilities, *cryptoOffer); - printf("negotiator->getCryptoSuite() %s\n", negotiator->getCryptoSuite().c_str()); - printf("negotiator->getKeyMethod() %s\n", negotiator->getKeyMethod().c_str()); - printf("negotiator->getKeyInfo() %s\n", negotiator->getKeyInfo().c_str()); - CPPUNIT_ASSERT(negotiator->negotiate() == true); - + CPPUNIT_ASSERT(negotiator->getCryptoSuite().compare("AES_CM_128_HMAC_SHA1_80") == 0); CPPUNIT_ASSERT(negotiator->getKeyMethod().compare("inline") == 0); CPPUNIT_ASSERT(negotiator->getKeyInfo().compare("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd") == 0); + CPPUNIT_ASSERT(negotiator->getLifeTime().compare("")== 0); + CPPUNIT_ASSERT(negotiator->getMkiValue().compare("")== 0); + CPPUNIT_ASSERT(negotiator->getMkiLength().compare("")== 0); delete capabilities; capabilities = NULL; delete cryptoOffer; cryptoOffer = NULL; diff --git a/sflphone-common/test/sdesnegotiatorTest.h b/sflphone-common/test/sdesnegotiatorTest.h index eb35c509e..88c8148a8 100644 --- a/sflphone-common/test/sdesnegotiatorTest.h +++ b/sflphone-common/test/sdesnegotiatorTest.h @@ -62,10 +62,11 @@ class SdesNegotiatorTest : public CppUnit::TestCase { * Use cppunit library macros to add unit test the factory */ CPPUNIT_TEST_SUITE( SdesNegotiatorTest ); - // CPPUNIT_TEST( testTagPattern ); - // CPPUNIT_TEST( testCryptoSuitePattern ); - // CPPUNIT_TEST( testKeyParamsPattern ); - // CPPUNIT_TEST( testNegotiation ); + CPPUNIT_TEST( testTagPattern ); + CPPUNIT_TEST( testCryptoSuitePattern ); + CPPUNIT_TEST( testKeyParamsPattern ); + CPPUNIT_TEST( testKeyParamsPatternWithoutMKI ); + CPPUNIT_TEST( testNegotiation ); CPPUNIT_TEST( testMostSimpleCase ); CPPUNIT_TEST_SUITE_END(); @@ -91,6 +92,8 @@ class SdesNegotiatorTest : public CppUnit::TestCase { void testKeyParamsPattern(); + void testKeyParamsPatternWithoutMKI(); + void testNegotiation(); void testComponent();