half-way through GxsTunnel service

This commit is contained in:
csoler 2015-11-18 23:56:35 -05:00
parent 7bcbc70d21
commit cb97ce6f72
4 changed files with 191 additions and 409 deletions

View File

@ -51,6 +51,13 @@ static const uint32_t RS_GXS_TUNNEL_DH_STATUS_UNINITIALIZED = 0x0000 ;
static const uint32_t RS_GXS_TUNNEL_DH_STATUS_HALF_KEY_DONE = 0x0001 ; static const uint32_t RS_GXS_TUNNEL_DH_STATUS_HALF_KEY_DONE = 0x0001 ;
static const uint32_t RS_GXS_TUNNEL_DH_STATUS_KEY_AVAILABLE = 0x0002 ; static const uint32_t RS_GXS_TUNNEL_DH_STATUS_KEY_AVAILABLE = 0x0002 ;
static const uint32_t RS_GXS_TUNNEL_STATUS_UNKNOWN = 0x00 ;
static const uint32_t RS_GXS_TUNNEL_STATUS_CAN_TALK = 0x01 ;
static const uint32_t RS_GXS_TUNNEL_STATUS_TUNNEL_DN = 0x02 ;
static const uint32_t GXS_TUNNEL_HMAC_SIZE = SHA_DIGEST_LENGTH ;
static const uint32_t GXS_TUNNEL_IV_SIZE = 8 ;
void p3GxsTunnelService::connectToTurtleRouter(p3turtle *tr) void p3GxsTunnelService::connectToTurtleRouter(p3turtle *tr)
{ {
mTurtle = tr ; mTurtle = tr ;
@ -93,7 +100,7 @@ void p3GxsTunnelService::flush()
} }
if(it->second.last_keep_alive_sent + GXS_TUNNEL_KEEP_ALIVE_TIMEOUT < now && it->second.status == RS_GXS_TUNNEL_STATUS_CAN_TALK) if(it->second.last_keep_alive_sent + GXS_TUNNEL_KEEP_ALIVE_TIMEOUT < now && it->second.status == RS_GXS_TUNNEL_STATUS_CAN_TALK)
{ {
RsChatStatusItem *cs = new RsChatStatusItem ; RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ;
#warning should we send that unencrypted?? #warning should we send that unencrypted??
cs->status_string.clear() ; cs->status_string.clear() ;
@ -112,7 +119,7 @@ void p3GxsTunnelService::flush()
} }
} }
bool p3GxsTunnelService::handleRecvItem(RsChatItem *item) bool p3GxsTunnelService::handleRecvItem(RsGxsTunnelItem *item)
{ {
if(item == NULL) if(item == NULL)
return false ; return false ;
@ -122,10 +129,15 @@ bool p3GxsTunnelService::handleRecvItem(RsChatItem *item)
case RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY: handleRecvDHPublicKey(dynamic_cast<RsGxsTunnelDHPublicKeyItem*>(item)) ; break ; case RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY: handleRecvDHPublicKey(dynamic_cast<RsGxsTunnelDHPublicKeyItem*>(item)) ; break ;
return true ; return true ;
case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS: #warning need to implement tunnel data handling here
{ case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA:
// Keep alive packets should not be forwarded to the GUI. It's just for keeping the tunnel up. return true ;
#warning need to implement tunnel data ACK handling here
case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK:
return true ;
case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS: handleRecvStatusItem(dynamic_cast<RsGxsTunnelStatusItem*>(item)) ;
return true ; return true ;
} }
@ -135,7 +147,9 @@ bool p3GxsTunnelService::handleRecvItem(RsChatItem *item)
return false ; return false ;
} }
bool p3GxsTunnelService::handleOutgoingItem(RsChatItem *item)
#warning is this function still used??
bool p3GxsTunnelService::handleOutgoingItem(RsGxsTunnelItem *item)
{ {
{ {
RS_STACK_MUTEX(mGxsTunnelMtx) ; RS_STACK_MUTEX(mGxsTunnelMtx) ;
@ -147,7 +161,7 @@ bool p3GxsTunnelService::handleOutgoingItem(RsChatItem *item)
} }
#ifdef CHAT_DEBUG #ifdef CHAT_DEBUG
std::cerr << "p3ChatService::handleOutgoingItem(): sending to " << item->PeerId() << ": interpreted as a distant chat virtual peer id." << std::endl; std::cerr << "p3GxsTunnelService::handleOutgoingItem(): sending to " << item->PeerId() << ": interpreted as a distant chat virtual peer id." << std::endl;
#endif #endif
sendTurtleData(item) ; sendTurtleData(item) ;
return true; return true;
@ -161,7 +175,7 @@ void p3GxsTunnelService::handleRecvStatusItem(RsGxsTunnelStatusItem *cs)
// nothing more to do, because the decryption routing will update the last_contact time when decrypting. // nothing more to do, because the decryption routing will update the last_contact time when decrypting.
if(cs->flags & RS_GXS_TUNNEL_FLAG_KEEP_ALIVE) if(cs->flags & RS_GXS_TUNNEL_FLAG_KEEP_ALIVE)
std::cerr << "GxsTunnelService::handleRecvChatStatusItem(): received keep alive packet for inactive tunnel! peerId=" << cs->PeerId() << std::endl; std::cerr << "GxsTunnelService::handleRecvGxsTunnelStatusItem(): received keep alive packet for inactive tunnel! peerId=" << cs->PeerId() << std::endl;
} }
bool p3GxsTunnelService::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& /*peer_id*/) bool p3GxsTunnelService::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& /*peer_id*/)
@ -350,8 +364,6 @@ void p3GxsTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,cons
std::cerr << "(EE) item encrypted data stream is too small: size = " << item->data_size << std::endl; std::cerr << "(EE) item encrypted data stream is too small: size = " << item->data_size << std::endl;
return ; return ;
} }
#warning use flags here!!
#warning add a MAC to make sure the data is not forged
if(*((uint64_t*)item->data_bytes) != 0) // WTF?? we should use flags if(*((uint64_t*)item->data_bytes) != 0) // WTF?? we should use flags
{ {
#ifdef DEBUG_GXS_TUNNEL #ifdef DEBUG_GXS_TUNNEL
@ -392,6 +404,7 @@ void p3GxsTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,cons
} }
} }
// This function encrypts the given data and adds a MAC and an IV into a serialised memory chunk that is then sent through the tunnel.
bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id) bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id)
{ {
@ -409,7 +422,9 @@ bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t
{ {
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
uint32_t decrypted_size = RsAES::get_buffer_size(data_size-8); uint32_t encrypted_size = data_size - GXS_TUNNEL_IV_SIZE - GXS_TUNNEL_HMAC_SIZE;
uint32_t decrypted_size = RsAES::get_buffer_size(encrypted_size);
uint8_t *encrypted_data = (uint8_t*)data_bytes+GXS_TUNNEL_IV_SIZE+GXS_TUNNEL_HMAC_SIZE;
uint8_t *decrypted_data = new uint8_t[decrypted_size]; uint8_t *decrypted_data = new uint8_t[decrypted_size];
uint8_t aes_key[GXS_TUNNEL_AES_KEY_SIZE] ; uint8_t aes_key[GXS_TUNNEL_AES_KEY_SIZE] ;
@ -434,11 +449,27 @@ bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t
#ifdef DEBUG_GXS_TUNNEL #ifdef DEBUG_GXS_TUNNEL
std::cerr << " Using IV: " << std::hex << *(uint64_t*)data_bytes << std::dec << std::endl; std::cerr << " Using IV: " << std::hex << *(uint64_t*)data_bytes << std::dec << std::endl;
std::cerr << " Decrypted buffer size: " << decrypted_size << std::endl; std::cerr << " Decrypted buffer size: " << decrypted_size << std::endl;
std::cerr << " key : " << Bin2Hex(aes_key,16) << ; std::cerr << std::endl; std::cerr << " key : " << Bin2Hex(aes_key,GXS_TUNNEL_AES_KEY_SIZE) << ; std::cerr << std::endl;
std::cerr << " hmac : " << Bin2Hex((uint8_t*)data_bytes+GXS_TUNNEL_IV_SIZE,GXS_TUNNEL_HMAC_SIZE) << ; std::cerr << std::endl;
std::cerr << " data : " << Bin2Hex((uint8_t*)data_bytes,data_size) << ; std::cerr << std::endl; std::cerr << " data : " << Bin2Hex((uint8_t*)data_bytes,data_size) << ; std::cerr << std::endl;
#endif #endif
// first, check the HMAC
if(!RsAES::aes_decrypt_8_16((uint8_t*)data_bytes+8,data_size-8,aes_key,(uint8_t*)data_bytes,decrypted_data,decrypted_size)) unsigned char *hm = HMAC(EVP_sha1(),aes_key,GXS_TUNNEL_AES_KEY_SIZE,encrypted_data,encrypted_size,NULL,NULL) ;
if(memcmp(hm,&data_bytes[GXS_TUNNEL_IV_SIZE],GXS_TUNNEL_HMAC_SIZE))
{
std::cerr << "(EE) packet HMAC does not match. Computed HMAC=" << Bin2Hex(md,GXS_TUNNEL_HMAC_SIZE) << std::endl;
std::cerr << "(EE) resetting new DH session." << std::endl;
delete[] decrypted_data ;
locked_restartDHSession(virtual_peer_id,it2->second.own_gxs_id) ;
return false ;
}
if(!RsAES::aes_decrypt_8_16(encrypted_data,encrypted_size, aes_key,(uint8_t*)data_bytes,decrypted_data,decrypted_size))
{ {
std::cerr << "(EE) packet decryption failed." << std::endl; std::cerr << "(EE) packet decryption failed." << std::endl;
std::cerr << "(EE) resetting new DH session." << std::endl; std::cerr << "(EE) resetting new DH session." << std::endl;
@ -750,7 +781,9 @@ bool GxsTunnelService::locked_initDHSessionKey(DH *& dh)
return true ; return true ;
} }
void p3GxsTunnelService::sendTurtleData(RsChatItem *item) // Encrypts and sends the item.
void p3GxsTunnelService::sendTurtleData(RsGxsTunnelItem *item)
{ {
#ifdef DEBUG_GXS_TUNNEL #ifdef DEBUG_GXS_TUNNEL
std::cerr << "GxsTunnelService::sendTurtleData(): try sending item " << (void*)item << " to peer " << item->PeerId() << std::endl; std::cerr << "GxsTunnelService::sendTurtleData(): try sending item " << (void*)item << " to peer " << item->PeerId() << std::endl;
@ -767,6 +800,7 @@ void p3GxsTunnelService::sendTurtleData(RsChatItem *item)
gitem->data_size = rssize + 8 ; gitem->data_size = rssize + 8 ;
gitem->data_bytes = malloc(rssize+8) ; gitem->data_bytes = malloc(rssize+8) ;
// by convention, we use a IV of 0 for unencrypted data.
memset(gitem->data_bytes,0,8) ; memset(gitem->data_bytes,0,8) ;
if(!item->serialise(&((uint8_t*)gitem->data_bytes)[8],rssize)) if(!item->serialise(&((uint8_t*)gitem->data_bytes)[8],rssize))
@ -842,10 +876,6 @@ void p3GxsTunnelService::sendEncryptedTurtleData(const uint8_t *buff,uint32_t rs
uint8_t *encrypted_data = new uint8_t[RsAES::get_buffer_size(rssize)]; uint8_t *encrypted_data = new uint8_t[RsAES::get_buffer_size(rssize)];
uint32_t encrypted_size = RsAES::get_buffer_size(rssize); uint32_t encrypted_size = RsAES::get_buffer_size(rssize);
#ifdef DEBUG_GXS_TUNNEL
std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl;
std::cerr << " Using Key: " << Bin2Hex(aes_key,16) ; std::cerr << std::endl;
#endif
if(!RsAES::aes_crypt_8_16(buff,rssize,aes_key,(uint8_t*)&IV,encrypted_data,encrypted_size)) if(!RsAES::aes_crypt_8_16(buff,rssize,aes_key,(uint8_t*)&IV,encrypted_data,encrypted_size))
{ {
std::cerr << "(EE) packet encryption failed." << std::endl; std::cerr << "(EE) packet encryption failed." << std::endl;
@ -857,18 +887,27 @@ void p3GxsTunnelService::sendEncryptedTurtleData(const uint8_t *buff,uint32_t rs
// //
RsTurtleGenericDataItem *gitem = new RsTurtleGenericDataItem ; RsTurtleGenericDataItem *gitem = new RsTurtleGenericDataItem ;
gitem->data_size = encrypted_size + 8 ; gitem->data_size = encrypted_size + GXS_TUNNEL_ENCRYPTION_IV_SIZE + GXS_TUNNEL_HMAC_SIZE ;
gitem->data_bytes = malloc(gitem->data_size) ; gitem->data_bytes = malloc(gitem->data_size) ;
memcpy(gitem->data_bytes ,&IV,8) ; memcpy(& (((uint8_t*)gitem->data_bytes)[0] ,&IV,8) ;
memcpy(& (((uint8_t*)gitem->data_bytes)[8]),encrypted_data,encrypted_size) ;
unsigned int md_len = GXS_TUNNEL_HMAC_SIZE ;
HMAC(EVP_sha1(),aes_key,GXS_TUNNEL_AES_KEY_SIZE,encrypted_data,encrypted_size,&(((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_IV_SIZE]),&md_len) ;
memcpy(& (((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_HMAC_SIZE+GXS_TUNNEL_IV_SIZE]),encrypted_data,encrypted_size) ;
delete[] encrypted_data ; delete[] encrypted_data ;
#ifdef DEBUG_GXS_TUNNEL
std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl;
std::cerr << " Using Key: " << Bin2Hex(aes_key,GXS_TUNNEL_AES_KEY_SIZE) ; std::cerr << std::endl;
std::cerr << " hmac: " << Bin2Hex(gitem->data_bytes,GXS_TUNNEL_HMAC_SIZE) ;
#endif
#ifdef DEBUG_GXS_TUNNEL #ifdef DEBUG_GXS_TUNNEL
std::cerr << "GxsTunnelService::sendTurtleData(): Sending encrypted data to virtual peer: " << virtual_peer_id << std::endl; std::cerr << "GxsTunnelService::sendTurtleData(): Sending encrypted data to virtual peer: " << virtual_peer_id << std::endl;
std::cerr << " gitem->data_size = " << gitem->data_size << std::endl; std::cerr << " gitem->data_size = " << gitem->data_size << std::endl;
std::cerr << " data = " << Bin2Hex(gitem->data_bytes,gitem->data_size) ; std::cerr << " serialised data = " << Bin2Hex(gitem->data_bytes,gitem->data_size) ;
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
@ -946,11 +985,11 @@ void p3GxsTunnelService::startClientGxsTunnelConnection(const RsGxsId& to_gxs_id
#warning check that this code should go. #warning check that this code should go.
#ifdef TO_BE_REMOVED #ifdef TO_BE_REMOVED
// spawn a status item so as to open the chat window. // spawn a status item so as to open the chat window.
RsChatMsgItem *item = new RsChatMsgItem; RsGxsTunnelMsgItem *item = new RsGxsTunnelMsgItem;
item->message = "[Starting distant chat. Please wait for secure tunnel to be established]" ; item->message = "[Starting distant chat. Please wait for secure tunnel to be established]" ;
item->chatFlags = RS_CHAT_FLAG_PRIVATE ; item->chatFlags = RS_CHAT_FLAG_PRIVATE ;
item->PeerId(RsPeerId(to_gxs_id)) ; item->PeerId(RsPeerId(to_gxs_id)) ;
handleRecvChatMsgItem(item) ; handleRecvGxsTunnelMsgItem(item) ;
#endif #endif
} }

View File

@ -27,6 +27,7 @@
#include <turtle/turtleclientservice.h> #include <turtle/turtleclientservice.h>
#include <retroshare/rsgxstunnel.h> #include <retroshare/rsgxstunnel.h>
#include <gxstunnel/rsgxstunnelitems.h>
class RsGixs ; class RsGixs ;
@ -120,7 +121,7 @@ private:
bool locked_sendDHPublicKey(const DH *dh, const RsGxsId& own_gxs_id, const RsPeerId& virtual_peer_id) ; bool locked_sendDHPublicKey(const DH *dh, const RsGxsId& own_gxs_id, const RsPeerId& virtual_peer_id) ;
bool locked_initDHSessionKey(DH *&dh); bool locked_initDHSessionKey(DH *&dh);
GxsTunnelPeerId virtualPeerIdFromHash(const TurtleFileHash& hash) ; // ... and to a hash for p3turtle TurtleVirtualPeerId virtualPeerIdFromHash(const TurtleFileHash& hash) ; // ... and to a hash for p3turtle
// Comunication with Turtle service // Comunication with Turtle service

View File

@ -25,7 +25,6 @@
#pragma once #pragma once
#include "openssl/bn.h"
#include "retroshare/rstypes.h" #include "retroshare/rstypes.h"
#include "serialiser/rstlvkeys.h" #include "serialiser/rstlvkeys.h"
#include "serialiser/rsserviceids.h" #include "serialiser/rsserviceids.h"
@ -35,60 +34,26 @@
#include "serialiser/rstlvfileitem.h" #include "serialiser/rstlvfileitem.h"
/* chat Flags */ /* chat Flags */
const uint32_t RS_CHAT_FLAG_PRIVATE = 0x0001; const uint32_t RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION = 0x0400;
const uint32_t RS_CHAT_FLAG_REQUESTS_AVATAR = 0x0002; const uint32_t RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION = 0x0800;
const uint32_t RS_CHAT_FLAG_CONTAINS_AVATAR = 0x0004; const uint32_t RS_GXS_TUNNEL_FLAG_KEEP_ALIVE = 0x1000;
const uint32_t RS_CHAT_FLAG_AVATAR_AVAILABLE = 0x0008;
const uint32_t RS_CHAT_FLAG_CUSTOM_STATE = 0x0010; // used for transmitting peer status string
const uint32_t RS_CHAT_FLAG_PUBLIC = 0x0020;
const uint32_t RS_CHAT_FLAG_REQUEST_CUSTOM_STATE = 0x0040;
const uint32_t RS_CHAT_FLAG_CUSTOM_STATE_AVAILABLE = 0x0080;
const uint32_t RS_CHAT_FLAG_PARTIAL_MESSAGE = 0x0100;
const uint32_t RS_CHAT_FLAG_LOBBY = 0x0200;
const uint32_t RS_CHAT_FLAG_CLOSING_DISTANT_CONNECTION = 0x0400;
const uint32_t RS_CHAT_FLAG_ACK_DISTANT_CONNECTION = 0x0800;
const uint32_t RS_CHAT_FLAG_KEEP_ALIVE = 0x1000;
const uint32_t RS_CHATMSG_CONFIGFLAG_INCOMING = 0x0001; const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DATA = 0x01 ;
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY = 0x02 ;
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS = 0x03 ;
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK = 0x04 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_AVATAR = 0x03 ; typedef uint64_t GxsTunnelDHSessionId ;
const uint8_t RS_PKT_SUBTYPE_CHAT_STATUS = 0x04 ;
const uint8_t RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG = 0x05 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_MSG_DEPRECATED = 0x06 ; // don't use ! Deprecated
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_DEPREC = 0x07 ; // don't use ! Deprecated
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_ACCEPT = 0x08 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE = 0x09 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE = 0x0A ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT_DEPREC = 0x0B ; // don't use ! Deprecated
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_MSG = 0x0C ; // will be deprecated when only signed messages are accepted (02/2015)
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST = 0x0D ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated = 0x0E ; // to be removed
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_deprecated = 0x0F ; // to be removed
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT = 0x10 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated2 = 0x11 ; // to be removed (deprecated since 02 Dec. 2012)
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated3 = 0x12 ;
const uint8_t RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG = 0x13 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG = 0x15 ;
const uint8_t RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY = 0x16 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_MSG = 0x17 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT = 0x18 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST = 0x19 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE = 0x1A ;
typedef uint64_t ChatLobbyId ; class RsGxsTunnelItem: public RsItem
typedef uint64_t ChatLobbyMsgId ;
typedef std::string ChatLobbyNickName ;
typedef uint64_t DistantChatDHSessionId ;
class RsChatItem: public RsItem
{ {
public: public:
RsChatItem(uint8_t chat_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_CHAT,chat_subtype) RsGxsTunnelItem(uint8_t item_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_GXS_TUNNEL,item_subtype)
{ {
setPriorityLevel(QOS_PRIORITY_RS_CHAT_ITEM) ; setPriorityLevel(QOS_PRIORITY_RS_CHAT_ITEM) ;
} }
virtual ~RsChatItem() {} virtual ~RsGxsTunnelItem() {}
virtual void clear() {} virtual void clear() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) = 0 ; virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) = 0 ;
@ -96,305 +61,80 @@ class RsChatItem: public RsItem
virtual uint32_t serial_size() = 0 ; // deserialise is handled using a constructor virtual uint32_t serial_size() = 0 ; // deserialise is handled using a constructor
}; };
/*! // /*!
* For sending chat msgs // * For sending distant communication data. The item is not encrypted after being serialised, but the data it.
* @see p3ChatService // * The MAC is computed over encrypted data using the PFS key. All other items (except DH keys) are serialised, encrypted, and
*/ // * sent as data in a RsGxsTunnelDataItem.
class RsChatMsgItem: public RsChatItem // *
{ // * @see p3GxsTunnelService
public: // */
RsChatMsgItem() :RsChatItem(RS_PKT_SUBTYPE_DEFAULT) {} // class RsGxsTunnelDataItem: public RsGxsTunnelItem
RsChatMsgItem(uint8_t subtype) :RsChatItem(subtype) {} // {
// public:
RsChatMsgItem(void *data,uint32_t size,uint8_t subtype = RS_PKT_SUBTYPE_DEFAULT) ; // deserialization // RsGxsTunnelDataItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA) {}
// RsGxsTunnelDataItem(uint8_t subtype) :RsGxsTunnelItem(subtype) {}
virtual ~RsChatMsgItem() {}
virtual void clear() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
uint32_t chatFlags;
uint32_t sendTime;
std::string message;
/* not serialised */
uint32_t recvTime;
};
// This class contains the info to bounce an object throughout a lobby, while
// maintaining cache info to avoid duplicates.
// //
class RsChatLobbyBouncingObject // virtual ~RsGxsTunnelDataItem() {}
{ // virtual void clear() {}
public: // virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
ChatLobbyId lobby_id ;
ChatLobbyMsgId msg_id ;
ChatLobbyNickName nick ; // Nickname of sender
RsTlvKeySignature signature ;
virtual RsChatLobbyBouncingObject *duplicate() const = 0 ;
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
// returns the size in bytes of the data chunk to sign.
virtual uint32_t signed_serial_size() =0;
virtual bool serialise_signed_part(void *data,uint32_t& size) = 0;
protected:
// The functions below handle the serialisation of data that is specific to the bouncing object level.
// They are called by serial_size() and serialise() from children, but should not overload the serial_size() and
// serialise() methods, otherwise the wrong method will be called when serialising from this top level class.
uint32_t serialized_size(bool include_signature) ;
bool serialise_to_memory(void *data,uint32_t tlvsize,uint32_t& offset,bool include_signature) ;
bool deserialise_from_memory(void *data,uint32_t rssize,uint32_t& offset) ;
};
class RsChatLobbyMsgItem: public RsChatMsgItem, public RsChatLobbyBouncingObject
{
public:
RsChatLobbyMsgItem() :RsChatMsgItem(RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_MSG) {}
RsChatLobbyMsgItem(void *data,uint32_t size) ; // deserialization /// TODO!!!
virtual ~RsChatLobbyMsgItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual RsChatLobbyBouncingObject *duplicate() const { return new RsChatLobbyMsgItem(*this) ; }
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
virtual uint32_t signed_serial_size() ;
virtual bool serialise_signed_part(void *data,uint32_t& size) ;// Isn't it better that items can serialize themselves ?
ChatLobbyMsgId parent_msg_id ; // Used for threaded chat.
};
class RsChatLobbyEventItem: public RsChatItem, public RsChatLobbyBouncingObject
{
public:
RsChatLobbyEventItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT) {}
RsChatLobbyEventItem(void *data,uint32_t size) ; // deserialization /// TODO!!!
virtual ~RsChatLobbyEventItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual RsChatLobbyBouncingObject *duplicate() const { return new RsChatLobbyEventItem(*this) ; }
//
virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
virtual uint32_t signed_serial_size() ;
virtual bool serialise_signed_part(void *data,uint32_t& size) ;
// members.
//
uint8_t event_type ; // used for defining the type of event.
std::string string1; // used for any string
uint32_t sendTime; // used to check for old looping messages
};
class RsChatLobbyListRequestItem: public RsChatItem
{
public:
RsChatLobbyListRequestItem() : RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST) {}
RsChatLobbyListRequestItem(void *data,uint32_t size) ;
virtual ~RsChatLobbyListRequestItem() {}
virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
};
struct VisibleChatLobbyInfo
{
ChatLobbyId id ;
std::string name ;
std::string topic ;
uint32_t count ;
ChatLobbyFlags flags ;
};
class RsChatLobbyListItem: public RsChatItem
{
public:
RsChatLobbyListItem() : RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_LIST) {}
RsChatLobbyListItem(void *data,uint32_t size) ;
virtual ~RsChatLobbyListItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
std::vector<VisibleChatLobbyInfo> lobbies ;
};
class RsChatLobbyUnsubscribeItem: public RsChatItem
{
public:
RsChatLobbyUnsubscribeItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE) {}
RsChatLobbyUnsubscribeItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatLobbyUnsubscribeItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
uint64_t lobby_id ;
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
};
class RsChatLobbyConnectChallengeItem: public RsChatItem
{
public:
RsChatLobbyConnectChallengeItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE) {}
RsChatLobbyConnectChallengeItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatLobbyConnectChallengeItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
uint64_t challenge_code ;
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
};
class RsChatLobbyInviteItem: public RsChatItem
{
public:
RsChatLobbyInviteItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE) {}
RsChatLobbyInviteItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatLobbyInviteItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
ChatLobbyId lobby_id ;
std::string lobby_name ;
std::string lobby_topic ;
ChatLobbyFlags lobby_flags ;
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
};
/*!
* For saving incoming and outgoing chat msgs
* @see p3ChatService
*/
class RsPrivateChatMsgConfigItem: public RsChatItem
{
public:
RsPrivateChatMsgConfigItem() :RsChatItem(RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG) {}
RsPrivateChatMsgConfigItem(void *data,uint32_t size) ; // deserialization
virtual ~RsPrivateChatMsgConfigItem() {}
virtual void clear() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
/* set data from RsChatMsgItem to RsPrivateChatMsgConfigItem */
void set(RsChatMsgItem *ci, const RsPeerId &peerId, uint32_t confFlags);
/* get data from RsPrivateChatMsgConfigItem to RsChatMsgItem */
void get(RsChatMsgItem *ci);
RsPeerId configPeerId;
uint32_t chatFlags;
uint32_t configFlags;
uint32_t sendTime;
std::string message;
uint32_t recvTime;
};
class RsPrivateChatDistantInviteConfigItem: public RsChatItem
{
public:
RsPrivateChatDistantInviteConfigItem() :RsChatItem(RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG) {}
RsPrivateChatDistantInviteConfigItem(void *data,uint32_t size) ; // deserialization
virtual ~RsPrivateChatDistantInviteConfigItem() {}
virtual void clear() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
unsigned char aes_key[16] ;
RsFileHash hash ;
std::string encrypted_radix64_string ;
RsPgpId destination_pgp_id ;
uint32_t time_of_validity ;
uint32_t last_hit_time ;
uint32_t flags ;
};
class RsChatLobbyConfigItem: public RsChatItem
{
public:
RsChatLobbyConfigItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG) { lobby_Id = 0; }
RsChatLobbyConfigItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatLobbyConfigItem() {}
virtual void clear() { lobby_Id = 0; }
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
uint64_t lobby_Id;
uint32_t flags ;
};
// This class contains activity info for the sending peer: active, idle, typing, etc.
// //
class RsChatStatusItem: public RsChatItem // virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
// virtual uint32_t serial_size() ; // deserialise is handled using a constructor
//
// uint32_t sendTime;
// uint32_t flags; // mainly NEEDS_HACK?
// unsigned char *data ; // encrypted data
// uint32_t data_size ; // encrypted data size
// unsigned char IV[IV_LENGTH] ; // IV for the encrypted data
// unsigned char encrypted_data_mac[SHA_DIGEST_LENGTH] ; // mac of the encrypted data, in order to avoid
// };
// Used to send status of connection. This can be closing orders, flushing orders, etc.
// These items are always sent encrypted.
class RsGxsTunnelStatusItem: public RsGxsTunnelItem
{ {
public: public:
RsChatStatusItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_STATUS) {} RsGxsTunnelStatusItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS) {}
RsChatStatusItem(void *data,uint32_t size) ; // deserialization RsGxsTunnelStatusItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatStatusItem() {} virtual ~RsGxsTunnelStatusItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor virtual uint32_t serial_size() ; // deserialise is handled using a constructor
uint32_t flags ; uint32_t flags ;
std::string status_string;
}; };
// This class contains avatar images in Qt format. // Used to confirm reception of an encrypted item.
//
class RsChatAvatarItem: public RsChatItem class RsGxsTunnelDataAckItem: public RsGxsTunnelItem
{ {
public: public:
RsChatAvatarItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_AVATAR) {setPriorityLevel(QOS_PRIORITY_RS_CHAT_AVATAR_ITEM) ;} RsGxsTunnelDataAckItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK) {}
RsChatAvatarItem(void *data,uint32_t size) ; // deserialization RsGxsTunnelDataAckItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatAvatarItem() ; virtual ~RsGxsTunnelDataAckItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor virtual uint32_t serial_size() ; // deserialise is handled using a constructor
uint32_t image_size ; // size of data in bytes Sha1CheckSum data_hash ;
unsigned char *image_data ; // image
}; };
// This class contains the public Diffie-Hellman parameters to be sent // This class contains the public Diffie-Hellman parameters to be sent
// when performing a DH agreement over a distant chat tunnel. // when performing a DH agreement over a distant chat tunnel.
// //
class RsChatDHPublicKeyItem: public RsChatItem class RsGxsTunnelDHPublicKeyItem: public RsGxsTunnelItem
{ {
public: public:
RsChatDHPublicKeyItem() :RsChatItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY) {setPriorityLevel(QOS_PRIORITY_RS_CHAT_ITEM) ;} RsGxsTunnelDHPublicKeyItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY) {}
RsChatDHPublicKeyItem(void *data,uint32_t size) ; // deserialization RsGxsTunnelDHPublicKeyItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatDHPublicKeyItem() { BN_free(public_key) ; } virtual ~RsGxsTunnelDHPublicKeyItem() { BN_free(public_key) ; }
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
@ -408,22 +148,23 @@ class RsChatDHPublicKeyItem: public RsChatItem
RsTlvSecurityKey gxs_key ; // public key of the signer RsTlvSecurityKey gxs_key ; // public key of the signer
private: private:
RsChatDHPublicKeyItem(const RsChatDHPublicKeyItem&) : RsChatItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY) {} // make the object non copy-able // make the object non copy-able
const RsChatDHPublicKeyItem& operator=(const RsChatDHPublicKeyItem&) { return *this ;} RsGxsTunnelDHPublicKeyItem(const RsGxsTunnelDHPublicKeyItem&) : RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY) {}
const RsGxsTunnelDHPublicKeyItem& operator=(const RsGxsTunnelDHPublicKeyItem&) { return *this ;}
}; };
class RsChatSerialiser: public RsSerialType class RsGxsTunnelSerialiser: public RsSerialType
{ {
public: public:
RsChatSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_CHAT) {} RsGxsTunnelSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_TUNNEL) {}
virtual uint32_t size (RsItem *item) virtual uint32_t size (RsItem *item)
{ {
return static_cast<RsChatItem *>(item)->serial_size() ; return static_cast<RsGxsTunnelItem *>(item)->serial_size() ;
} }
virtual bool serialise(RsItem *item, void *data, uint32_t *size) virtual bool serialise(RsItem *item, void *data, uint32_t *size)
{ {
return static_cast<RsChatItem *>(item)->serialise(data,*size) ; return static_cast<RsGxsTunnelItem *>(item)->serialise(data,*size) ;
} }
virtual RsItem *deserialise (void *data, uint32_t *size) ; virtual RsItem *deserialise (void *data, uint32_t *size) ;
}; };

View File

@ -60,6 +60,7 @@ const uint16_t RS_SERVICE_TYPE_DISTANT_MAIL = 0x0024;
const uint16_t RS_SERVICE_TYPE_GWEMAIL_MAIL = 0x0025; const uint16_t RS_SERVICE_TYPE_GWEMAIL_MAIL = 0x0025;
const uint16_t RS_SERVICE_TYPE_SERVICE_CONTROL= 0x0026; const uint16_t RS_SERVICE_TYPE_SERVICE_CONTROL= 0x0026;
const uint16_t RS_SERVICE_TYPE_DISTANT_CHAT = 0x0027; const uint16_t RS_SERVICE_TYPE_DISTANT_CHAT = 0x0027;
const uint16_t RS_SERVICE_TYPE_GXS_TUNNEL = 0x0028;
// Non essential services. // Non essential services.
const uint16_t RS_SERVICE_TYPE_BANLIST = 0x0101; const uint16_t RS_SERVICE_TYPE_BANLIST = 0x0101;