diff --git a/sflphone-client-gnome/src/config/accountconfigdialog.c b/sflphone-client-gnome/src/config/accountconfigdialog.c index 2fe773469b4eb17031f39a8c0ed032a1c9f846bb..b103db80ba035f6eeb0722de5d6cc28de5871316 100644 --- a/sflphone-client-gnome/src/config/accountconfigdialog.c +++ b/sflphone-client-gnome/src/config/accountconfigdialog.c @@ -50,7 +50,7 @@ GtkWidget * hbox; GtkWidget * label; GtkWidget * entryID; GtkWidget * entryAlias; -GtkWidget * entryProtocol; +GtkWidget * protocolComboBox; GtkWidget * entryUsername; GtkWidget * entryHostname; GtkWidget * entryPassword; @@ -78,6 +78,9 @@ GtkWidget * stunServerLabel; GtkWidget * stunServerEntry; GtkWidget * displayNameEntry; + +GtkWidget * security_tab; +GtkWidget * advanced_tab; // Credentials enum { @@ -88,11 +91,19 @@ enum { COLUMN_CREDENTIAL_COUNT }; -/* Signal to entryProtocol 'changed' */ +/* Signal to protocolComboBox 'changed' */ void -change_protocol (account_t * currentAccount UNUSED) +change_protocol_cb (account_t * currentAccount UNUSED) { - (gchar *)gtk_combo_box_get_active_text(GTK_COMBO_BOX(entryProtocol)); + gchar * protocol = gtk_combo_box_get_active_text(GTK_COMBO_BOX(protocolComboBox)); + + if (g_strcasecmp(protocol, "IAX") == 0) { + gtk_widget_hide(security_tab); + gtk_widget_hide(advanced_tab); + } else { + gtk_widget_show(security_tab); + gtk_widget_show(advanced_tab); + } } int @@ -170,29 +181,29 @@ static GtkWidget * create_basic_tab(account_t **a) label = gtk_label_new_with_mnemonic (_("_Protocol")); gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); - entryProtocol = gtk_combo_box_new_text(); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), entryProtocol); - gtk_combo_box_append_text(GTK_COMBO_BOX(entryProtocol), "SIP"); - if( is_iax_enabled() ) gtk_combo_box_append_text(GTK_COMBO_BOX(entryProtocol), "IAX"); + protocolComboBox = gtk_combo_box_new_text(); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), protocolComboBox); + gtk_combo_box_append_text(GTK_COMBO_BOX(protocolComboBox), "SIP"); + if( is_iax_enabled() ) gtk_combo_box_append_text(GTK_COMBO_BOX(protocolComboBox), "IAX"); if(strcmp(curAccountType, "SIP") == 0) { - gtk_combo_box_set_active(GTK_COMBO_BOX(entryProtocol),0); + gtk_combo_box_set_active(GTK_COMBO_BOX(protocolComboBox),0); } else if(strcmp(curAccountType, "IAX") == 0) { - gtk_combo_box_set_active(GTK_COMBO_BOX(entryProtocol),1); + gtk_combo_box_set_active(GTK_COMBO_BOX(protocolComboBox),1); } else { /* Should never come here, add debug message. */ - gtk_combo_box_append_text(GTK_COMBO_BOX(entryProtocol), _("Unknown")); - gtk_combo_box_set_active(GTK_COMBO_BOX(entryProtocol),2); + gtk_combo_box_append_text(GTK_COMBO_BOX(protocolComboBox), _("Unknown")); + gtk_combo_box_set_active(GTK_COMBO_BOX(protocolComboBox),2); } - gtk_table_attach ( GTK_TABLE( table ), entryProtocol, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach ( GTK_TABLE( table ), protocolComboBox, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); /* Link signal 'changed' */ - g_signal_connect (G_OBJECT (GTK_COMBO_BOX(entryProtocol)), "changed", - G_CALLBACK (change_protocol), + g_signal_connect (G_OBJECT (GTK_COMBO_BOX(protocolComboBox)), "changed", + G_CALLBACK (change_protocol_cb), currentAccount); label = gtk_label_new_with_mnemonic (_("_Host name")); @@ -890,22 +901,24 @@ show_account_window (account_t * a) gtk_notebook_page_num(GTK_NOTEBOOK(notebook), tab); /* Advanced */ - tab = create_advanced_tab(¤tAccount); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tab, gtk_label_new(_("Advanced"))); - gtk_notebook_page_num(GTK_NOTEBOOK(notebook), tab); + advanced_tab = create_advanced_tab(¤tAccount); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), advanced_tab, gtk_label_new(_("Advanced"))); + gtk_notebook_page_num(GTK_NOTEBOOK(notebook), advanced_tab); /* Security */ - tab = create_security_tab(¤tAccount); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tab, gtk_label_new(_("Security"))); - gtk_notebook_page_num(GTK_NOTEBOOK(notebook), tab); + security_tab = create_security_tab(¤tAccount); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), security_tab, gtk_label_new(_("Security"))); + gtk_notebook_page_num(GTK_NOTEBOOK(notebook),security_tab); gtk_notebook_set_current_page( GTK_NOTEBOOK( notebook) , 0); + g_signal_emit_by_name(protocolComboBox, "changed", NULL); + response = gtk_dialog_run (GTK_DIALOG (dialog)); if(response == GTK_RESPONSE_ACCEPT) { - gchar* proto = (gchar *)gtk_combo_box_get_active_text(GTK_COMBO_BOX(entryProtocol)); + gchar* proto = (gchar *)gtk_combo_box_get_active_text(GTK_COMBO_BOX(protocolComboBox)); g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_RESOLVE_ONCE), diff --git a/sflphone-common/src/sip/Regex.cpp b/sflphone-common/src/sip/Regex.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b285f227f5e3c11f9d24d8a64038fb79dd2ec07a --- /dev/null +++ b/sflphone-common/src/sip/Regex.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2009 Savoir-Faire Linux inc. + * Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MEstatusHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "Regex.h" + +#include <sstream> + +namespace sfl { + + const int MAX_SUBSTRINGS = 30; + + Regex::Regex(const std::string& pattern) : + _pattern(pattern) + ,_pcreOutputVector(NULL) + ,_re(NULL) + { + compile(); + } + + Regex::~Regex() + { + pcre_free(_re); + delete[] _pcreOutputVector; + } + + void Regex::compile(void) + { + // Compile the pattern + int offset; + const char * error; + + _reMutex.enterMutex(); + _re = pcre_compile(_pattern.c_str(), 0, &error, &offset, NULL); + + if (_re == NULL) { + std::string offsetStr; + std::stringstream ss; + ss << offset; + offsetStr = ss.str(); + + std::string msg("PCRE compiling failed at offset "); + + throw compile_error(msg); + } + + // Allocate space for + // the output vector + if (_pcreOutputVector != NULL) { + delete[] _pcreOutputVector; + } + _pcreOutputVector = new int[MAX_SUBSTRINGS]; + _reMutex.leaveMutex(); + } + + const std::vector<std::string>& Regex::findall(const std::string& subject) + { + // Execute the PCRE regex + int status; + + _reMutex.enterMutex(); + status = pcre_exec(_re, NULL, subject.c_str(), subject.length(), + 0, 0, _pcreOutputVector, MAX_SUBSTRINGS); + _reMutex.leaveMutex(); + + // Handle error cases + if (status < 0) { + + // Free the regular expression + pcre_free(_re); + + // Throw and exception + switch(status) { + case PCRE_ERROR_NOMATCH: + throw match_error("No match"); + break; + default: + std::string statusStr; + std::stringstream ss; + ss << status - 1; + statusStr = ss.str(); + + throw match_error(std::string("Matching error number ") + + statusStr + std::string(" occured")); + break; + } + + } + // Output_vector isn't big enough + if (status == 0) { + + status = MAX_SUBSTRINGS/3; + + std::string statusStr; + std::stringstream ss; + ss << status - 1; + statusStr = ss.str(); + + throw std::length_error(std::string("Output vector is not big enough. Has room for") + + statusStr + std::string("captured substrings\n")); + } + + // Copy the contents to the std::vector that will be + // handed to the user + int count = status; + const char **stringlist; + + _reMutex.enterMutex(); + status = pcre_get_substring_list(subject.c_str(), _pcreOutputVector, count, &stringlist); + if (status < 0) { + fprintf(stderr, "Get substring list failed"); + } else { + _outputVector.clear(); + + int i; + for (i = 0; i < count; i++) { + _outputVector.push_back(stringlist[i]); + } + + pcre_free_substring_list(stringlist); + + } + _reMutex.leaveMutex(); + + return _outputVector; + } + + range Regex::finditer(const std::string& subject) + { + findall(subject); + std::vector<std::string>::iterator iterBegin = _outputVector.begin(); + std::vector<std::string>::iterator iterEnd = _outputVector.end(); + return range(iterBegin, iterEnd); + } + + std::string Regex::group(const std::string& groupName) + { + _reMutex.enterMutex(); + + // Executes the regex + findall(_subject); + + // Access the named substring + const char * substring; + std::string substringReturned; + + int rc = pcre_get_named_substring(_re, _subject.c_str(), _pcreOutputVector, + _outputVector.size(), groupName.c_str(), &substring); + + // Handle errors + if (rc < 0) { + + switch(rc) { + case PCRE_ERROR_NOMEMORY: + throw match_error("Couln't get memory"); + break; + case PCRE_ERROR_NOSUBSTRING: + throw match_error("No such captured substring"); + break; + default: + throw match_error("Error copying substring"); + } + + } else { + substringReturned = substring; + pcre_free_substring(substring); + } + _reMutex.leaveMutex(); + + return substringReturned; + } +} + diff --git a/sflphone-common/src/sip/Regex.h b/sflphone-common/src/sip/Regex.h new file mode 100644 index 0000000000000000000000000000000000000000..613f707a9a48d1f882e551e2d0d9cf5be3d27fa0 --- /dev/null +++ b/sflphone-common/src/sip/Regex.h @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2009 Savoir-Faire Linux inc. + * Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __SFL_REGEX_H__ +#define __SFL_REGEX_H__ + +#include <stdexcept> +#include <ostream> +#include <vector> + +#include <pcre.h> +#include <cc++/thread.h> + +namespace sfl { + + /** + * While waiting for C++0x to come out + * Let's say that we have something like + * std::range + * + * Defines a pair of iterator over a vector of + * strings. The fist element corresponds to the + * begining of the vector, while the second is + * set to the end. + */ + typedef std::pair<std::vector<std::string>::iterator, std::vector<std::string>::iterator> range; + + /** + * Exception object that is thrown when + * an error occured while compiling the + * regular expression. + */ + class compile_error : public std::invalid_argument + { + public: + explicit compile_error(const std::string& error) : + std::invalid_argument(error) {} + }; + + /** + * Exception object that is thrown when + * an error occured while mathing a + * pattern to an expression. + */ + class match_error : public std::invalid_argument + { + public: + match_error(const std::string& error) : + std::invalid_argument(error) {} + }; + + /** + * This class implements in its way + * some of the libpcre library. + */ + + class Regex { + + public: + + /** + * Constructor for a regular expression + * pattern evaluator/matcher. + * + * @param pattern + * The regular expression to + * be used for this instance. + */ + + Regex(const std::string& pattern = ""); + + ~Regex(); + + /** + * Set the regular expression + * to be used on subject strings + * + * @param pattern The new pattern + */ + + void setPattern(const std::string& pattern) { + _reMutex.enterMutex(); + _pattern = pattern; + _reMutex.leaveMutex(); + } + + /** + * Assignment operator overloading. + * Set the regular expression + * to be used on subject strings + * and compile the regular expression + * from that string. + * + * You should use the setPattern() method to + * only set the variable itself, then manually + * compile the expression with the compile() + * method. + * + * @param pattern The new pattern + */ + + void operator=(const std::string& pattern) { + _reMutex.enterMutex(); + _pattern = pattern; + _reMutex.leaveMutex(); + compile(); + } + + void operator=(const char * pattern) { + _reMutex.enterMutex(); + _pattern = pattern; + _reMutex.leaveMutex(); + compile(); + } + + /** + * Compile the regular expression + * from the pattern that was set for + * this object. + */ + + void compile(void); + + /** + * Get the currently set regular expression + * that is used on subject strings + * + * @return The currently set pattern + */ + + inline std::string getPattern(void) { return _pattern; } + + /** + * Match the given expression against + * this pattern and returns a vector of + * the substrings that were matched. + * + * @param subject + * The expression to be evaluated + * by the pattern. + * + * @return a vector containing the substrings + * in the order that the parentheses were + * defined. Throws a match_error if the + * expression cannot be matched. + */ + + const std::vector<std::string>& findall(const std::string& subject); + + /** + * << operator overload. Sets the the subject + * for latter use on the >> operator. + * + * @param subject + * The expression to be evaluated + * by the pattern. + * + */ + + void operator<<(const std::string& subject) { + _reMutex.enterMutex(); + _subject = subject; + _reMutex.leaveMutex(); + } + + /** + * >> operator overload. Executes the + * findall method with the subject previously + * set with the << operator. + * + * @return a vector containing the substrings + * in the order that the parentheses were + * defined. Throws a match_error if the + * expression cannot be matched. + */ + + void operator>>(std::vector<std::string>& outputVector) { + _reMutex.enterMutex(); + outputVector = findall(_subject); + _reMutex.leaveMutex(); + } + + /** + * Match the given expression against + * this pattern and returns an iterator + * to the substrings. + * + * @param subject + * The expression to be evaluated + * by the pattern. + * + * @return an iterator to the output vector + * containing the substrings that + * were matched. + */ + + range finditer(const std::string& subject); + + /** + * Try to match the regular expression + * on the subject previously set in this + * object and return the substring matched + * by the given group name. + * + * @param groupName The name of the group + * @return the substring matched by the + * regular expression designated + * the group name. + */ + std::string group(const std::string& groupName); + + private: + + /** + * The regular expression that represents that pattern + */ + + std::string _pattern; + + /** + * The optional subject string that can be used + * by the << and >> operator. + */ + + std::string _subject; + + /** + * The pcre regular expression structure + */ + + pcre * _re; + + /** + * The output vector used to contain + * substrings that were matched by pcre. + */ + + int * _pcreOutputVector; + + /** + * The output std::vector used to contain + * substrings that were matched by pcre. + */ + + std::vector<std::string> _outputVector; + + /** + * Protects the above data from concurrent + * access. + */ + + ost::Mutex _reMutex; + }; + +} + +#endif diff --git a/sflphone-common/src/sip/SdesNegotiator.cpp b/sflphone-common/src/sip/SdesNegotiator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f7d4a4b0bc2a336c31e6ce474ed3010999c213a --- /dev/null +++ b/sflphone-common/src/sip/SdesNegotiator.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2009 Savoir-Faire Linux inc. + * Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "SdesNegotiator.h" + +#include "regex.h" + +#include <iostream> +#include <sstream> +#include <algorithm> +#include <stdexcept> + +namespace sfl { + + struct CryptoAttribute { + std::string tag; + std::string cryptoSuite; + std::string keyParams; + std::string sessionParams; + }; + + SdesNegotiator::SdesNegotiator(const std::vector<CryptoSuiteDefinition>& localCapabilites, const std::vector<std::string>& remoteAttribute) : + _remoteAttribute(remoteAttribute), + _localCapabilities(localCapabilites) + { + + } + + CryptoAttribute * SdesNegotiator::tokenize(const std::string& attributeLine) + { + // Split the line into at most + // 4 components corresponding to + // a=crypto:<tag> <crypto-suite> <key-params> [<session-params>] + size_t pos; + const char WSP = ' '; + std::string line(attributeLine); + + pos = line.rfind(WSP); + + std::string token; + std::vector<std::string> lineSplitted; + + while (pos != std::string::npos && lineSplitted.size() != 4) { + + token = line.substr(pos+1); + lineSplitted.push_back(token); + + token = line.substr(0, pos); + line = token; + + pos = line.rfind(WSP); + + } + + lineSplitted.push_back(line); + + CryptoAttribute * cryptoLine; + // Build up the new CryptoAttribute + try { + cryptoLine = new CryptoAttribute(); + } catch (std::bad_alloc&) { + std::cerr << "Failed create new CryptoLine" << std::endl; + throw; + } + + std::reverse(lineSplitted.begin(), lineSplitted.end()); + + cryptoLine->tag = lineSplitted.at(0); + cryptoLine->cryptoSuite = lineSplitted.at(1); + cryptoLine->keyParams = lineSplitted.at(2); + if (lineSplitted.size() == 4) { + cryptoLine->sessionParams = lineSplitted.at(3); + } + + return cryptoLine; + } + + bool SdesNegotiator::parse(void) + { + std::vector<std::string>::iterator iter; + + for (iter = _remoteAttribute.begin(); iter != _remoteAttribute.end(); iter++) { + + // Split the line into components + // and build up a CryptoAttribute + // structure. + CryptoAttribute * cryptoLine; + try { + cryptoLine = tokenize((*iter)); + } catch (...) { + std::cerr << "An exception occured" << std::endl; + } + + // Check if we have the right kind of attribute + if (cryptoLine->tag.find("a=crypto:") != 0) { + std::cout << cryptoLine->tag << std::endl; + throw std::runtime_error("Bad syntax"); + } + + // Find index + size_t tagPos; + tagPos = cryptoLine->tag.find(":"); + if (tagPos == std::string::npos) { + throw std::runtime_error("Bad syntax"); + } + + std::string index; + index = cryptoLine->tag.substr(tagPos+1); + + std::cout << "index:" << index << std::endl; + // Make sure its less than 9 digit long + + if (index.length() > 9) { + throw std::runtime_error("Index too long."); + } + + int tagIndex; + std::istringstream ss(index); + ss >> tagIndex; + if (ss.fail()) { + throw std::runtime_error("Bad conversion"); + } + + // Check if the given crypto-suite is valid + // by looking in our list. + // Extension: 1*(ALPHA / DIGIT / "_") + int i; + for (i = 0; i < 3; i++) { + if (cryptoLine->cryptoSuite.compare(CryptoSuites[i].name) == 0) { + break; + } + } + + if (i == 3) { + std::cout << "This is an unhandled extension\n" << std::endl; + } + + // Parse the key-params + // Check it starts with a valid key-method + if (cryptoLine->keyParams.find("inline:") != 0) { + throw std::runtime_error("Unsupported key-method\n"); + } + + KeyMethod method = Inline; + + // Find concatenated key and salt values + + + } + + + } + + bool SdesNegotiator::negotiate(void) + { + parse(); + } +} diff --git a/sflphone-common/src/sip/SdesNegotiator.h b/sflphone-common/src/sip/SdesNegotiator.h new file mode 100644 index 0000000000000000000000000000000000000000..a88811c6d2cb67f4cdbcf42c9dc3d24d1c524abd --- /dev/null +++ b/sflphone-common/src/sip/SdesNegotiator.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2009 Savoir-Faire Linux inc. + * Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __SFL_SDES_NEGOTIATOR_H__ +#define __SFL_SDES_NEGOTIATOR_H__ + +#include <vector> +#include <string> + +namespace sfl { + + enum CipherMode { + AESCounterMode, + AESF8Mode + }; + + enum MACMode { + HMACSHA1 + }; + + enum KeyMethod { + Inline + // url, maybe at some point + }; + + struct CryptoSuiteDefinition { + char * name; + int masterKeyLength; + int masterSaltLength; + int srtpLifetime; + int srtcpLifetime; + CipherMode cipher; + int encryptionKeyLength; + MACMode mac; + int srtpAuthTagLength; + int srtcpAuthTagLength; + int srtpAuthKeyLength; + int srtcpAuthKeyLen; + }; + + /** + * List of accepted Crypto-Suites + * as defined in RFC4568 (6.2) + */ + const CryptoSuiteDefinition CryptoSuites[3] = { + {"AES_CM_128_HMAC_SHA1_80", 128, 112, 48, 31, AESCounterMode, 128, HMACSHA1, 80, 80, 160, 160 }, + {"AES_CM_128_HMAC_SHA1_32", 128, 112, 48, 31, AESCounterMode, 128, HMACSHA1, 32, 80, 160, 160 }, + {"F8_128_HMAC_SHA1_80", 128, 112, 48, 31, AESF8Mode, 128, HMACSHA1, 80, 80, 160, 160 } }; + + /** + * Internal structure + * used during parsing. + */ + struct CryptoAttribute; + + class SdesNegotiator + { + /** + * Constructor for an SDES crypto attributes + * negotiator. + * + * @param attribute + * A vector of crypto attributes as defined in + * RFC4568. This string will be parsed + * and a crypto context will be created + * from it. + */ + + public: + SdesNegotiator(const std::vector<CryptoSuiteDefinition>& localCapabilites, const std::vector<std::string>& remoteAttribute); + ~SdesNegotiator() { }; + + public: + bool negotiate(void); + + private: + /** + * A vector list containing the remote attributes. + * Multiple crypto lines can be sent, and the + * prefered method is then chosen from that list. + */ + std::vector<std::string> _remoteAttribute; + std::vector<CryptoSuiteDefinition> _localCapabilities; + + + + private: + bool parse(void); + CryptoAttribute * tokenize(const std::string& attributeLine); + }; +} +#endif diff --git a/sflphone-common/src/sip/testRegex.cpp b/sflphone-common/src/sip/testRegex.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e947932fc31b6df70c94bc0961ab29093c64ef5a --- /dev/null +++ b/sflphone-common/src/sip/testRegex.cpp @@ -0,0 +1,100 @@ +#include "Regex.h" +#include <iostream> +#include <algorithm> + +std::string regularExpression = "^a=crypto:([0-9]{1,9})" \ + "[\x20\x09](AES_CM_128_HMAC_SHA1_80|AES_CM_128_HMAC_SHA1_32|F8_128_HMAC_SHA1_80|[A-Za-z0-9_]+)" \ + "[\x20\x09](inline|[A-Za-z0-9_]+)\\:([A-Za-z0-9\x2B\x2F\x3D]+)\\|2\\^([0-9]+)\\|([0-9]+)\\:([0-9]{1,3})\\;?" \ + "[\x20\x09]?(kdr\\=[0-9]{1,2}|UNENCRYPTED_SRTP|UNENCRYPTED_SRTCP|UNAUTHENTICATED_SRTP|(FEC_ORDER)=(FEC_SRTP|SRTP_FEC)" \ + "|(FEC_KEY)=|(WSH)=([0-9]{1,2})|(?<!\\-)[[:graph:]]+)*"; + +std::string subject = "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32 kdr=12"; + +void printSubstring(const std::string& substring) +{ + std::cout << substring << std::endl; +} + +void testFindMethods(void) +{ + // Test the find methods + // + std::cout << "Testing pattern 1" << std::endl; + + sfl::Regex pattern(regularExpression); + + // Test the findall method + std::vector<std::string> substring = pattern.findall(subject); + std:for_each(substring.begin(), substring.end(), printSubstring); + + // Test the finditer method + sfl::range range = pattern.finditer(subject); + std::for_each(range.first, range.second, printSubstring); + + // Instanciate a new Regex object + // but set the pattern only after + // the constructor was called. + std::cout << std::endl << "Testing pattern 2" << std::endl; +} + +void testOperators(void) +{ + sfl::Regex pattern2; + + pattern2.setPattern(regularExpression); + pattern2.compile(); + + sfl::range range = pattern2.finditer(subject); + std::for_each(range.first, range.second, printSubstring); + + // Instanciate a new Regex object + // but set the pattern only after + // the constructor was called. + // Use the = operator to set the + // regular expression. + std::cout << std::endl << "Testing pattern 3" << std::endl; + + sfl::Regex pattern3; + + pattern3 = regularExpression; + + range = pattern3.finditer(subject); + std::for_each(range.first, range.second, printSubstring); + + // Test the << and >> operators + std::cout << std::endl << "Testing pattern 4" << std::endl; + sfl::Regex pattern4; + + pattern4 = regularExpression; + + pattern4 << subject; + + std::vector<std::string> outputVector; + pattern4 >> outputVector; + std::for_each(outputVector.begin(), outputVector.end(), printSubstring); +} + +void testGroup(void) +{ + std::cout << std::endl << "Testing group feature" << std::endl; + + sfl::Regex pattern; + + pattern = "^a=crypto:(?P<tag>[0-9]{1,9})"; + + pattern << subject; + + std::string substring = pattern.group("tag"); + + std::cout << "Substring: " << substring << std::endl; +} + +int main(void) +{ + testFindMethods(); + testOperators(); + testGroup(); + + return 0; +} +