Commit 0dcefce5 authored by Yann Garcia's avatar Yann Garcia
Browse files

Enhance SIP support, Validation LIS/Lost

parent 8c4e7ca0
Loading
Loading
Loading
Loading
+82 −1
Original line number Diff line number Diff line
#include <algorithm>
#include <string>
#include <regex>

#include <openssl/md5.h>

#include "LibSip_Steps.hh"

#include "loggers.hh"

#include "converter.hh"

namespace LibSip__Steps {

  int calculate_md5(const std::string& p_data, std::string& p_md5)
  {
    loggers::get_instance().log(">>> calculate_md5: %s", p_data.c_str());

    MD5_CTX md5_context;
    ::MD5_Init(&md5_context);
    
    loggers::get_instance().log("calculate_md5: length=%d", p_data.length());
    ::MD5_Update(&md5_context, p_data.c_str(), p_data.length()); // TODO Add support of block size > 512
    
    const size_t digestlen = 16;
    unsigned char digest[digestlen];
    ::MD5_Final(digest, &md5_context);
    p_md5 = converter::get_instance().bytes_to_hexa(std::vector<unsigned char>(digest, digest + digestlen));
    
    loggers::get_instance().log("<<< calculate_md5: %s", p_md5.c_str());
    return 0;
  }
  
  CHARSTRING fx__rndStr() {
    static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    static int length = 10;
@@ -22,7 +46,64 @@ namespace LibSip__Steps {
    std::transform(s.begin(), s.end(), s.begin(), ::tolower);
    return CHARSTRING(s.c_str());
  };
  
  CHARSTRING fx__getIpAddr(const CHARSTRING& p__host__name) { return CHARSTRING(""); };
  CHARSTRING fx__calculateDigestResponse(const CHARSTRING& p__nonce, const CHARSTRING& p__cnonce, const CHARSTRING& p__user, const CHARSTRING& p__realm, const CHARSTRING& p__passwd, const CHARSTRING& p__alg, const CHARSTRING& p__nonceCount, const CHARSTRING& p__method, const CHARSTRING& p__qop, const CHARSTRING& p__URI, const CHARSTRING& p__HEntity) { return CHARSTRING(""); };
  
  CHARSTRING fx__calculateDigestResponse(const CHARSTRING& p__nonce, const CHARSTRING& p__cnonce, const CHARSTRING& p__user, const CHARSTRING& p__realm, const CHARSTRING& p__passwd, const CHARSTRING& p__alg, const CHARSTRING& p__nonceCount, const CHARSTRING& p__method, const CHARSTRING& p__qop, const CHARSTRING& p__URI, const CHARSTRING& p__HEntity) {
    loggers::get_instance().log(">>> fx__calculateDigestResponse");

    // Buid a1=USERNAME:REALM:PASSWORD
    std::string a1(static_cast<const char*>(p__user));
    a1 += ":";
    a1 += static_cast<const char*>(p__realm);
    a1 += ":";
    a1 += static_cast<const char*>(p__passwd);
    if (a1.find("\"") != std::string::npos) {
      a1 = std::regex_replace(a1, std::regex("\""), "");
    }
    loggers::get_instance().log("fx__calculateDigestResponse: a1='%s'", a1.c_str());
    std::string md5_a1;
    calculate_md5(a1, md5_a1);
    
    // Buid a2=METHOD:DIGESTURI
    std::string a2(static_cast<const char*>(p__method));
    a2 += ":";
    a2 += static_cast<const char*>(p__URI);
    if (a2.find("\"") != std::string::npos) {
      a2 = std::regex_replace(a2, std::regex("\""), ""); // TODO Move to converter
    }
    loggers::get_instance().log("fx__calculateDigestResponse: a2='%s'", a2.c_str());
    std::string md5_a2;
    calculate_md5(a2, md5_a2);
    
    // Buid resp=HA1:NONCE:HA2
    std::string resp(md5_a1);
    resp += ":";
    resp += static_cast<const char*>(p__nonce);
    resp += ":";
    resp += md5_a2;
    loggers::get_instance().log("fx__calculateDigestResponse: resp='%s'", resp.c_str());
    std::string md5_resp;
    calculate_md5(resp, md5_resp);

    // Convert into Base64
    std::vector<unsigned char> u = converter::get_instance().string_to_bytes(md5_resp);
    md5_resp = converter::get_instance().bytes_to_string(converter::get_instance().buffer_to_base64(u));
    
    loggers::get_instance().log("<<< fx__calculateDigestResponse: '%s'", md5_resp.c_str());
    return CHARSTRING(md5_resp.c_str());
  };
  
  CHARSTRING fx__encodeBase64(const CHARSTRING& p__value) {
    std::vector<unsigned char> s(static_cast<const char*>(p__value), static_cast<const char*>(p__value) + p__value.lengthof());
    std::vector<unsigned char> o = converter::get_instance().buffer_to_base64(s);
    return CHARSTRING(o.size(), (const char*)o.data());
  };
  
  CHARSTRING fx__decodeBase64(const CHARSTRING& p__value) {
    std::vector<unsigned char> s(static_cast<const char*>(p__value), static_cast<const char*>(p__value) + p__value.lengthof());
    std::vector<unsigned char> o = converter::get_instance().base64_to_buffer(s);
    return CHARSTRING(o.size(), (const char*)o.data());
  };
  
} // End of namespace LibSip__Steps
+37 −4
Original line number Diff line number Diff line
@@ -114,13 +114,13 @@ public:
   * \param[in] p_value The string value
   * \return The hexadecimal value
   */
  std::string string_to_hexa(const std::string & p_value);
  std::string string_to_hexa(const std::string & p_value, const bool p_uppercase = false);
  /*!
   * \brief Convert a bytes array int32_t an hexadecimal string
   * \param[in] p_value The bytes array value
   * \return The hexadecimal value
   */
  std::string bytes_to_hexa(const std::vector<uint8_t> & p_value);
  std::string bytes_to_hexa(const std::vector<uint8_t> & p_value, const bool p_uppercase = false);
  /*!
   * \brief Convert an hexadecimal string into a bytes array
   * \param[in] p_value The hexadecimal value
@@ -328,6 +328,22 @@ public:
    return ss.str();
  }; // End of string_to_bytes

  /*!
   * \brief Convert a string in to lower case
   * \param[in/out] p_value The string value to convert
   */
  inline void to_lower(std::string& p_value) {
    std::transform(p_value.begin(), p_value.end(), p_value.begin(), ::tolower);
  }
  
  /*!
   * \brief Convert a string in to upper case
   * \param[in/out] p_value The string value to convert
   */
  inline void to_upper(std::string& p_value) {
    std::transform(p_value.begin(), p_value.end(), p_value.begin(), ::toupper);
  }
  
public:
  
  /*!
@@ -369,5 +385,22 @@ public:
   */
  std::vector<std::string> split_arguments_line(const std::string & p_value);
  
  static const std::string lut;
  /*!
   * \brief Convert the provided buffer into a Base64
   * \param[in] p_value The buffer value
   * \return The Base64 encoded buffert
   */
  std::vector<unsigned char> buffer_to_base64(const std::vector<unsigned char> & p_value);
  
  /*!
   * \brief Convert the provided Base64 buffer 
   * \param[in] p_value The buffer value
   * \return The Base64 encoded buffert
   */
  std::vector<unsigned char> base64_to_buffer(const std::vector<unsigned char> & p_value);

  static const std::string lut_u;
  static const std::string lut_l;
  static const std::string base64_enc_map;
  
}; // End of class converter
+84 −17
Original line number Diff line number Diff line
@@ -12,8 +12,9 @@ uint32_t converter::swap(const uint32_t p_value) {
  return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
}
    
const std::string converter::lut = "0123456789ABCDEF";
std::string converter::string_to_hexa(const std::string & p_value) {
const std::string converter::lut_u = "0123456789ABCDEF";
const std::string converter::lut_l = "0123456789abcdef";
std::string converter::string_to_hexa(const std::string & p_value, const bool p_uppercase) {

  std::string input(p_value);
  std::for_each(
@@ -27,30 +28,49 @@ std::string converter::string_to_hexa(const std::string & p_value) {
  std::string output;
  uint32_t length = p_value.length();
  output.reserve(2 * length);
  if (p_uppercase) { // TODO Use pointer to reduce code size
    for (uint32_t i = 0; i < length; ++i) {
      const uint8_t c = input[i];
    output.push_back(lut[c >> 4]);
    output.push_back(lut[c & 15]);
      output.push_back(lut_u[c >> 4]);
      output.push_back(lut_u[c & 15]);
    } // End of 'for' statement
  } else {
    for (uint32_t i = 0; i < length; ++i) {
      const uint8_t c = input[i];
      output.push_back(lut_l[c >> 4]);
      output.push_back(lut_l[c & 15]);
    } // End of 'for' statement
  }
   
  return output;
}
    
std::string converter::bytes_to_hexa(const std::vector<uint8_t> & p_value) {
std::string converter::bytes_to_hexa(const std::vector<uint8_t> & p_value, const bool p_uppercase) {
  std::string ret;
  ret.assign(p_value.size()*2, ' ');
  if (p_uppercase) { // TODO Use pointer to reduce code size
    for(size_t i=0; i<p_value.size(); i++){
      uint8_t c = p_value[i];
      ret[i*2] = lut_u[c>>4];
      ret[i*2+1] = lut_u[c&0xF];
    }
  } else {
    for(size_t i=0; i<p_value.size(); i++){
      uint8_t c = p_value[i];
    ret[i*2] = lut[c>>4]; 
    ret[i*2+1] = lut[c&0xF];
      ret[i*2] = lut_l[c>>4]; 
      ret[i*2+1] = lut_l[c&0xF];
    }
  }
  return ret;
}

inline uint8_t char2byte(const char ch) {
  size_t s = converter::lut.find(ch);
  if(s == std::string::npos)
inline uint8_t char2byte(const char p_ch) {
  size_t s = converter::lut_l.find(p_ch);
  if(s == std::string::npos) {
    if ((s = converter::lut_u.find(p_ch)) == std::string::npos) {
      throw (std::length_error(""));
    }
  }
  return s;
}

@@ -133,3 +153,50 @@ std::vector<std::string> converter::split_arguments_line(const std::string & p_v
  } // else, invalid command line
  return output;
}

const std::string converter::base64_enc_map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

std::vector<unsigned char> converter::buffer_to_base64(const std::vector<unsigned char> & p_value) {
  std::vector<unsigned char> out;
  
  int val = 0, valb = -6;
  for (unsigned char c : p_value) {
    val = (val << 8) + c;
    valb += 8;
    while (valb >= 0) {
      out.push_back(converter::base64_enc_map[(val >> valb) & 0x3F]);
      valb -= 6;
    } // End of 'while' statement
  } // End of 'for' statement
  if (valb > -6) {
    out.push_back(converter::base64_enc_map[((val << 8) >> (valb + 8)) & 0x3F]);
  }
  while (out.size() % 4) {
    out.push_back('=');
  } // End of 'while' statement
  
  return out;
}

std::vector<unsigned char> converter::base64_to_buffer(const std::vector<unsigned char> &p_value) {
  std::vector<unsigned char> out;
  
  std::vector<int> T(256, -1);
  for (int i = 0; i < 64; i++) {
    T[converter::base64_enc_map[i]] = i;
  }
  
  int val = 0, valb = -8;
  for (unsigned char c : p_value) {
    if (T[c] == -1) {
      break;
    }
    val = (val << 6) + T[c];
    valb += 6;
    if (valb >= 0) {
      out.push_back((unsigned char)char((val >> valb) & 0xFF));
      valb -= 8;
    }
  } // End of 'for' statement
  return out;
}
+48 −0
Original line number Diff line number Diff line
@@ -96,6 +96,10 @@ namespace LibSip__Interface {

    if (p_ind.requestLine().method() == LibSip__SIPTypesAndValues::Method::INVITE__E) {
      incoming_message(LibSip__SIPTypesAndValues::INVITE__Request(p_ind.requestLine(), p_ind.msgHeader(), p_ind.messageBody(), p_ind.payload()));
    } else if (p_ind.requestLine().method() == LibSip__SIPTypesAndValues::Method::NOTIFY__E) {
      incoming_message(LibSip__SIPTypesAndValues::NOTIFY__Request(p_ind.requestLine(), p_ind.msgHeader(), p_ind.messageBody(), p_ind.payload()));
    } else if (p_ind.requestLine().method() == LibSip__SIPTypesAndValues::Method::BYE__E) {
      incoming_message(LibSip__SIPTypesAndValues::BYE__Request(p_ind.requestLine(), p_ind.msgHeader(), p_ind.messageBody(), p_ind.payload()));
    } else {
      incoming_message(p_ind);
    }
@@ -124,5 +128,49 @@ namespace LibSip__Interface {
    loggers::get_instance().set_stop_time(_time_key, duration);
  } // End of outgoing_send
  
  void SipPort::outgoing_send(const LibSip__SIPTypesAndValues::REGISTER__Request& send_par, const Address4SIP *destination_address) {
    loggers::get_instance().log_msg(">>> SipPort::outgoing_send: ", send_par);
    loggers::get_instance().log(">>> SipPort::outgoing_send: %s", destination_address);

    float duration;
    loggers::get_instance().set_start_time(_time_key);
    params params;
    static_cast<sip_layer*>(_layer)->sendMsg(send_par, params);
    loggers::get_instance().set_stop_time(_time_key, duration);
  }
  
  void SipPort::outgoing_send(const LibSip__SIPTypesAndValues::SUBSCRIBE__Request& send_par, const Address4SIP *destination_address) {
    loggers::get_instance().log_msg(">>> SipPort::outgoing_send: ", send_par);
    loggers::get_instance().log(">>> SipPort::outgoing_send: %s", destination_address);

    float duration;
    loggers::get_instance().set_start_time(_time_key);
    params params;
    static_cast<sip_layer*>(_layer)->sendMsg(send_par, params);
    loggers::get_instance().set_stop_time(_time_key, duration);
  }
  
  void SipPort::outgoing_send(const LibSip__SIPTypesAndValues::MESSAGE__Request& send_par, const Address4SIP *destination_address) {
    loggers::get_instance().log_msg(">>> SipPort::outgoing_send: ", send_par);
    loggers::get_instance().log(">>> SipPort::outgoing_send: %s", destination_address);

    float duration;
    loggers::get_instance().set_start_time(_time_key);
    params params;
    static_cast<sip_layer*>(_layer)->sendMsg(send_par, params);
    loggers::get_instance().set_stop_time(_time_key, duration);
  }
  
  void SipPort::outgoing_send(const LibSip__SIPTypesAndValues::OPTIONS__Request& send_par, const Address4SIP *destination_address) {
    loggers::get_instance().log_msg(">>> SipPort::outgoing_send: ", send_par);
    loggers::get_instance().log(">>> SipPort::outgoing_send: %s", destination_address);

    float duration;
    loggers::get_instance().set_start_time(_time_key);
    params params;
    static_cast<sip_layer*>(_layer)->sendMsg(send_par, params);
    loggers::get_instance().set_stop_time(_time_key, duration);
  }
  
}
+4 −4
Original line number Diff line number Diff line
@@ -42,19 +42,19 @@ namespace LibSip__Interface {

  protected:
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::Request& send_par, const Address4SIP *destination_address) { };
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::REGISTER__Request& send_par, const Address4SIP *destination_address) { };
    void outgoing_send(const LibSip__SIPTypesAndValues::REGISTER__Request& send_par, const Address4SIP *destination_address);
    void outgoing_send(const LibSip__SIPTypesAndValues::INVITE__Request& send_par, const Address4SIP *destination_address);
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::OPTIONS__Request& send_par, const Address4SIP *destination_address) { };
    void outgoing_send(const LibSip__SIPTypesAndValues::OPTIONS__Request& send_par, const Address4SIP *destination_address);
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::BYE__Request& send_par, const Address4SIP *destination_address) { };
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::CANCEL__Request& send_par, const Address4SIP *destination_address) { };
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::ACK__Request& send_par, const Address4SIP *destination_address) { };
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::PRACK__Request& send_par, const Address4SIP *destination_address) { };
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::NOTIFY__Request& send_par, const Address4SIP *destination_address) { };
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::SUBSCRIBE__Request& send_par, const Address4SIP *destination_address) { };
    void outgoing_send(const LibSip__SIPTypesAndValues::SUBSCRIBE__Request& send_par, const Address4SIP *destination_address);
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::PUBLISH__Request& send_par, const Address4SIP *destination_address) { };
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::UPDATE__Request& send_par, const Address4SIP *destination_address) { };
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::REFER__Request& send_par, const Address4SIP *destination_address) { };
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::MESSAGE__Request& send_par, const Address4SIP *destination_address) { };
    void outgoing_send(const LibSip__SIPTypesAndValues::MESSAGE__Request& send_par, const Address4SIP *destination_address);
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::INFO__Request& send_par, const Address4SIP *destination_address) { };
    virtual void outgoing_send(const LibSip__SIPTypesAndValues::Response& send_par, const Address4SIP *destination_address) { };
    virtual void outgoing_send(const CHARSTRING& send_par, const Address4SIP *destination_address) { };
Loading