mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Added signature verification in distant messages. Decrypted does not always work due to openpgp limitations.
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6551 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
f27b2368ab
commit
dc7003bd92
@ -59,6 +59,8 @@
|
||||
#define RS_MSG_FRIEND_RECOMMENDATION 0x0800 /* friend recommendation */
|
||||
#define RS_MSG_SYSTEM (RS_MSG_USER_REQUEST | RS_MSG_FRIEND_RECOMMENDATION)
|
||||
#define RS_MSG_ENCRYPTED 0x1000 /* message is encrypted */
|
||||
#define RS_MSG_SIGNATURE_CHECKS 0x2000 /* message was signed, and signature checked */
|
||||
#define RS_MSG_SIGNED 0x4000 /* message was signed and signature didn't check */
|
||||
|
||||
#define RS_CHAT_LOBBY_EVENT_PEER_LEFT 0x01
|
||||
#define RS_CHAT_LOBBY_EVENT_PEER_STATUS 0x02
|
||||
|
@ -412,23 +412,25 @@ class RsChatSerialiser: public RsSerialType
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
const uint32_t RS_MSG_FLAGS_OUTGOING = 0x0001;
|
||||
const uint32_t RS_MSG_FLAGS_PENDING = 0x0002;
|
||||
const uint32_t RS_MSG_FLAGS_DRAFT = 0x0004;
|
||||
const uint32_t RS_MSG_FLAGS_NEW = 0x0010;
|
||||
const uint32_t RS_MSG_FLAGS_TRASH = 0x0020;
|
||||
const uint32_t RS_MSG_FLAGS_UNREAD_BY_USER = 0x0040;
|
||||
const uint32_t RS_MSG_FLAGS_REPLIED = 0x0080;
|
||||
const uint32_t RS_MSG_FLAGS_FORWARDED = 0x0100;
|
||||
const uint32_t RS_MSG_FLAGS_STAR = 0x0200;
|
||||
const uint32_t RS_MSG_FLAGS_PARTIAL = 0x0400;
|
||||
const uint32_t RS_MSG_FLAGS_OUTGOING = 0x00000001;
|
||||
const uint32_t RS_MSG_FLAGS_PENDING = 0x00000002;
|
||||
const uint32_t RS_MSG_FLAGS_DRAFT = 0x00000004;
|
||||
const uint32_t RS_MSG_FLAGS_NEW = 0x00000010;
|
||||
const uint32_t RS_MSG_FLAGS_TRASH = 0x00000020;
|
||||
const uint32_t RS_MSG_FLAGS_UNREAD_BY_USER = 0x00000040;
|
||||
const uint32_t RS_MSG_FLAGS_REPLIED = 0x00000080;
|
||||
const uint32_t RS_MSG_FLAGS_FORWARDED = 0x00000100;
|
||||
const uint32_t RS_MSG_FLAGS_STAR = 0x00000200;
|
||||
const uint32_t RS_MSG_FLAGS_PARTIAL = 0x00000400;
|
||||
// system message
|
||||
const uint32_t RS_MSG_FLAGS_USER_REQUEST = 0x0800;
|
||||
const uint32_t RS_MSG_FLAGS_FRIEND_RECOMMENDATION = 0x1000;
|
||||
const uint32_t RS_MSG_FLAGS_USER_REQUEST = 0x00000800;
|
||||
const uint32_t RS_MSG_FLAGS_FRIEND_RECOMMENDATION = 0x00001000;
|
||||
const uint32_t RS_MSG_FLAGS_SYSTEM = RS_MSG_FLAGS_USER_REQUEST | RS_MSG_FLAGS_FRIEND_RECOMMENDATION;
|
||||
const uint32_t RS_MSG_FLAGS_RETURN_RECEPT = 0x2000;
|
||||
const uint32_t RS_MSG_FLAGS_ENCRYPTED = 0x4000;
|
||||
const uint32_t RS_MSG_FLAGS_DISTANT = 0x8000;
|
||||
const uint32_t RS_MSG_FLAGS_RETURN_RECEPT = 0x00002000;
|
||||
const uint32_t RS_MSG_FLAGS_ENCRYPTED = 0x00004000;
|
||||
const uint32_t RS_MSG_FLAGS_DISTANT = 0x00008000;
|
||||
const uint32_t RS_MSG_FLAGS_SIGNATURE_CHECKS = 0x00010000;
|
||||
const uint32_t RS_MSG_FLAGS_SIGNED = 0x00020000;
|
||||
|
||||
class RsMsgItem: public RsItem
|
||||
{
|
||||
|
@ -54,6 +54,8 @@ static const uint32_t RS_DISTANT_MSG_STATUS_TUNNEL_OK = 0x0001 ;
|
||||
static const uint32_t RS_DISTANT_MSG_STATUS_TUNNEL_DN = 0x0000 ;
|
||||
static const uint32_t DISTANT_MSG_HASH_SIZE = 20 ;
|
||||
|
||||
static const uint8_t ENCRYPTED_MSG_PROTOCOL_VERSION_01 = 0x37 ;
|
||||
|
||||
/* Another little hack ..... unique message Ids
|
||||
* will be handled in this class.....
|
||||
* These are unique within this run of the server,
|
||||
@ -1400,6 +1402,12 @@ void p3MsgService::initRsMI(RsMsgItem *msg, MessageInfo &mi)
|
||||
mi.msgflags |= RS_MSG_NEW;
|
||||
}
|
||||
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_SIGNED)
|
||||
mi.msgflags |= RS_MSG_SIGNED ;
|
||||
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_SIGNATURE_CHECKS)
|
||||
mi.msgflags |= RS_MSG_SIGNATURE_CHECKS ;
|
||||
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_ENCRYPTED)
|
||||
mi.msgflags |= RS_MSG_ENCRYPTED ;
|
||||
|
||||
@ -1491,6 +1499,12 @@ void p3MsgService::initRsMIS(RsMsgItem *msg, MsgInfoSummary &mis)
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_ENCRYPTED)
|
||||
mis.msgflags |= RS_MSG_ENCRYPTED ;
|
||||
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_SIGNED)
|
||||
mis.msgflags |= RS_MSG_SIGNED ;
|
||||
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_SIGNATURE_CHECKS)
|
||||
mis.msgflags |= RS_MSG_SIGNATURE_CHECKS ;
|
||||
|
||||
/* translate flags, if we sent it... outgoing */
|
||||
if ((msg->msgFlags & RS_MSG_FLAGS_OUTGOING)
|
||||
/*|| (msg->PeerId() == mLinkMgr->getOwnId())*/)
|
||||
@ -1609,6 +1623,9 @@ RsMsgItem *p3MsgService::initMIRsMsg(MessageInfo &info, const std::string &to)
|
||||
if (info.msgflags & RS_MSG_FRIEND_RECOMMENDATION)
|
||||
msg->msgFlags |= RS_MSG_FLAGS_FRIEND_RECOMMENDATION;
|
||||
|
||||
if (info.msgflags & RS_MSG_SIGNED)
|
||||
msg->msgFlags |= RS_MSG_FLAGS_SIGNED;
|
||||
|
||||
// See if we need to encrypt this message. If so, we replace the msg text
|
||||
// by the whole message serialized and binary encrypted, so as to obfuscate
|
||||
// all its content.
|
||||
@ -1628,32 +1645,96 @@ bool p3MsgService::encryptMessage(const std::string& pgp_id,RsMsgItem *item)
|
||||
std::cerr << "Encrypting message with public key " << pgp_id << " in place." << std::endl;
|
||||
#endif
|
||||
|
||||
// 1 - serialise the whole message item into a binary chunk.
|
||||
// 0 - happend own id to the data.
|
||||
//
|
||||
uint32_t rssize = _serialiser->size(item) ;
|
||||
unsigned char *data = new unsigned char[rssize] ;
|
||||
unsigned char *data = (unsigned char *)malloc(1+rssize+KEY_ID_SIZE) ;
|
||||
|
||||
if(!_serialiser->serialise(item,data,&rssize))
|
||||
// -1 - setup protocol version
|
||||
//
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " adding protocol version TAG = " << std::hex << (int)ENCRYPTED_MSG_PROTOCOL_VERSION_01 << std::dec << std::endl;
|
||||
#endif
|
||||
data[0] = ENCRYPTED_MSG_PROTOCOL_VERSION_01 ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " adding own key ID " << AuthGPG::getAuthGPG()->getGPGOwnId() << std::endl;
|
||||
#endif
|
||||
memcpy(&data[1], PGPIdType(AuthGPG::getAuthGPG()->getGPGOwnId()).toByteArray(), KEY_ID_SIZE) ;
|
||||
|
||||
// 1 - serialise the whole message item into a binary chunk.
|
||||
//
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " serialising item..." << std::endl;
|
||||
#endif
|
||||
if(!_serialiser->serialise(item,&data[1+KEY_ID_SIZE],&rssize))
|
||||
{
|
||||
std::cerr << "(EE) p3MsgService::sendTurtleData(): Serialization error." << std::endl;
|
||||
delete[] data ;
|
||||
free(data) ;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2 - pgp-encrypt the chunk with the user-supplied public key.
|
||||
// 2 - now sign the data, if necessary, and put the signature up front
|
||||
|
||||
uint32_t signature_length = 0 ;
|
||||
unsigned char *signature_data = NULL ;
|
||||
|
||||
if(item->msgFlags & RS_MSG_FLAGS_SIGNED)
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Signing the message..." << std::endl;
|
||||
#endif
|
||||
signature_length = 2000 ;
|
||||
signature_data = new unsigned char[signature_length] ;
|
||||
|
||||
if(!AuthGPG::getAuthGPG()->SignDataBin(data,1+rssize+KEY_ID_SIZE,signature_data,&signature_length))
|
||||
{
|
||||
free(data) ;
|
||||
std::cerr << "Signature failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " After signature: signature size = " << signature_length << std::endl;
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " total decrypted size = " << KEY_ID_SIZE + 1 + rssize + signature_length << std::endl;
|
||||
#endif
|
||||
// 3 - happend the signature to the serialized data.
|
||||
|
||||
if(signature_length > 0)
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Appending signature." << std::endl;
|
||||
#endif
|
||||
data = (uint8_t*)realloc(data,1+rssize+signature_length+KEY_ID_SIZE) ;
|
||||
memcpy(&data[1+rssize+KEY_ID_SIZE],signature_data,signature_length) ;
|
||||
}
|
||||
|
||||
// 2 - pgp-encrypt the whole chunk with the user-supplied public key.
|
||||
//
|
||||
uint32_t encrypted_size = rssize + 1000 ;
|
||||
uint32_t encrypted_size = 1+rssize + KEY_ID_SIZE + signature_length + 1000 ;
|
||||
unsigned char *encrypted_data = new unsigned char[encrypted_size] ;
|
||||
|
||||
if(!AuthGPG::getAuthGPG()->encryptDataBin(pgp_id,data,rssize,encrypted_data,&encrypted_size))
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Encrypting for Key ID " << pgp_id << std::endl;
|
||||
#endif
|
||||
if(!AuthGPG::getAuthGPG()->encryptDataBin(pgp_id,data,1+rssize+signature_length+KEY_ID_SIZE,encrypted_data,&encrypted_size))
|
||||
{
|
||||
delete[] data ;
|
||||
free(data) ;
|
||||
delete[] encrypted_data ;
|
||||
std::cerr << "Encryption failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
delete[] data ;
|
||||
free(data) ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Decrypted size = " << 1+rssize+signature_length+KEY_ID_SIZE << std::endl;
|
||||
std::cerr << " Encrypted size = " << encrypted_size << std::endl;
|
||||
std::cerr << " First bytes of encrypted data: " << std::hex << (int)encrypted_data[0] << " " << (int)encrypted_data[1] << " " << (int)encrypted_data[2] << std::dec << std::endl;
|
||||
std::cerr << " Encrypted data hash = " << RsDirUtil::sha1sum(encrypted_data,encrypted_size).toStdString() << std::endl;
|
||||
#endif
|
||||
// Now turn the binary encrypted chunk into a readable radix string.
|
||||
//
|
||||
std::string armoured_data ;
|
||||
@ -1662,6 +1743,9 @@ bool p3MsgService::encryptMessage(const std::string& pgp_id,RsMsgItem *item)
|
||||
|
||||
std::wstring encrypted_msg ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Converting to radix64" << std::endl;
|
||||
#endif
|
||||
if(!librs::util::ConvertUtf8ToUtf16(armoured_data,encrypted_msg))
|
||||
return false;
|
||||
|
||||
@ -1675,6 +1759,9 @@ bool p3MsgService::encryptMessage(const std::string& pgp_id,RsMsgItem *item)
|
||||
item->msgFlags |= RS_MSG_FLAGS_ENCRYPTED ;
|
||||
item->attachment.TlvClear() ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Done" << std::endl;
|
||||
#endif
|
||||
return true ;
|
||||
}
|
||||
|
||||
@ -1710,6 +1797,11 @@ bool p3MsgService::decryptMessage(const std::string& mId)
|
||||
uint32_t decrypted_size = encrypted_size + 500 ;
|
||||
unsigned char *decrypted_data = new unsigned char[decrypted_size] ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Calling decryption. Encrypted data size = " << encrypted_size << ", Allocated size = " << decrypted_size << std::endl;
|
||||
std::cerr << " First bytes of encrypted data: " << std::hex << (int)((unsigned char*)encrypted_data)[0] << " " << (int)((unsigned char*)encrypted_data)[1] << " " << (int)((unsigned char*)encrypted_data)[2] << std::dec << std::endl;
|
||||
std::cerr << " Encrypted data hash = " << RsDirUtil::sha1sum((uint8_t*)encrypted_data,encrypted_size).toStdString() << std::endl;
|
||||
#endif
|
||||
if(!AuthGPG::getAuthGPG()->decryptDataBin(encrypted_data,encrypted_size,decrypted_data,&decrypted_size))
|
||||
{
|
||||
delete[] encrypted_data ;
|
||||
@ -1718,10 +1810,36 @@ bool p3MsgService::decryptMessage(const std::string& mId)
|
||||
return false;
|
||||
}
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << "Message has succesfully decrypted." << std::endl;
|
||||
std::cerr << " Message has succesfully decrypted. Decrypted size = " << decrypted_size << std::endl;
|
||||
#endif
|
||||
|
||||
RsMsgItem *item = dynamic_cast<RsMsgItem*>(_serialiser->deserialise(decrypted_data,&decrypted_size)) ;
|
||||
// 1 - get the sender's id
|
||||
|
||||
unsigned char protocol_version = decrypted_data[0] ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Read protocol version number " << std::hex << (int)protocol_version << std::dec << std::endl;
|
||||
#endif
|
||||
if(protocol_version != ENCRYPTED_MSG_PROTOCOL_VERSION_01)
|
||||
{
|
||||
std::cerr << "Bad version number " << std::hex << (int)protocol_version << std::dec << " => packet is dropped." << std::endl;
|
||||
delete[] encrypted_data ;
|
||||
delete[] decrypted_data ;
|
||||
return false;
|
||||
}
|
||||
|
||||
PGPIdType senders_id(&decrypted_data[1]) ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Sender's ID: " << senders_id.toStdString() << std::endl;
|
||||
#endif
|
||||
// 2 - deserialize the item
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Deserializing..." << std::endl;
|
||||
#endif
|
||||
uint32_t item_size = decrypted_size ; // just needs to be larger than the actual size.
|
||||
RsMsgItem *item = dynamic_cast<RsMsgItem*>(_serialiser->deserialise(&decrypted_data[1+KEY_ID_SIZE],&item_size)) ;
|
||||
|
||||
if(item == NULL)
|
||||
{
|
||||
@ -1729,6 +1847,38 @@ bool p3MsgService::decryptMessage(const std::string& mId)
|
||||
return false ;
|
||||
}
|
||||
|
||||
// 3 - check signature
|
||||
|
||||
bool signature_present = false ;
|
||||
bool signature_ok = false ;
|
||||
|
||||
if(1+item_size + KEY_ID_SIZE < decrypted_size)
|
||||
{
|
||||
std::cerr << " Signature is present. Verifying it..." << std::endl;
|
||||
|
||||
PGPFingerprintType fingerprint ;
|
||||
if(!AuthGPG::getAuthGPG()->getKeyFingerprint(senders_id,fingerprint))
|
||||
{
|
||||
std::cerr << "Cannot get fingerprint" << std::endl;
|
||||
return false ;
|
||||
}
|
||||
std::cerr << " Fingerprint = " << fingerprint.toStdString() << std::endl;
|
||||
|
||||
signature_present = true ;
|
||||
signature_ok = AuthGPG::getAuthGPG()->VerifySignBin(decrypted_data, 1+KEY_ID_SIZE+item_size, &decrypted_data[1+KEY_ID_SIZE+item_size], decrypted_size - KEY_ID_SIZE - item_size - 1, fingerprint.toStdString()) ;
|
||||
}
|
||||
else if(1 + item_size + KEY_ID_SIZE == decrypted_size)
|
||||
std::cerr << " No signature in this packet" << std::endl;
|
||||
else
|
||||
{
|
||||
std::cerr << "Structural error in packet: sizes do not match. Dropping the message." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
delete[] decrypted_data ;
|
||||
|
||||
// 4 - replace the item with the decrypted data, and update flags
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Decrypted message was succesfully deserialized. New message:" << std::endl;
|
||||
item->print(std::cerr,0) ;
|
||||
@ -1742,6 +1892,17 @@ bool p3MsgService::decryptMessage(const std::string& mId)
|
||||
msgi = *item ; // copy everything
|
||||
msgi.msgId = msgId ; // restore the correct message id, to make it consistent
|
||||
msgi.msgFlags &= ~RS_MSG_FLAGS_ENCRYPTED ; // just in case.
|
||||
msgi.PeerId(senders_id.toStdString()) ;
|
||||
|
||||
if(signature_present)
|
||||
{
|
||||
msgi.msgFlags |= RS_MSG_FLAGS_SIGNED ;
|
||||
|
||||
if(signature_ok)
|
||||
msgi.msgFlags |= RS_MSG_FLAGS_SIGNATURE_CHECKS ; // just in case.
|
||||
else
|
||||
msgi.msgFlags &= ~RS_MSG_FLAGS_SIGNATURE_CHECKS ; // just in case.
|
||||
}
|
||||
}
|
||||
delete item ;
|
||||
|
||||
@ -1972,7 +2133,7 @@ void p3MsgService::removeVirtualPeer(const TurtleFileHash& hash, const TurtleVir
|
||||
remove_tunnel = true ;
|
||||
}
|
||||
|
||||
if(remove_tunnel)
|
||||
if(remove_tunnel) // We do that whenever we're client or server. But normally, we should only do it when we're client.
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << "Also removing tunnel, since pending messages have been sent." << std::endl;
|
||||
@ -1997,22 +2158,23 @@ void p3MsgService::sendTurtleData(const std::string& hash,RsMsgItem *msgitem)
|
||||
{
|
||||
// The item is serialized and turned into a generic turtle item.
|
||||
|
||||
uint32_t rssize = _serialiser->size(msgitem) ;
|
||||
unsigned char *data = new unsigned char[rssize] ;
|
||||
uint32_t msg_serialized_rssize = _serialiser->size(msgitem) ;
|
||||
unsigned char *msg_serialized_data = new unsigned char[msg_serialized_rssize] ;
|
||||
|
||||
if(!_serialiser->serialise(msgitem,data,&rssize))
|
||||
if(!_serialiser->serialise(msgitem,msg_serialized_data,&msg_serialized_rssize))
|
||||
{
|
||||
std::cerr << "(EE) p3MsgService::sendTurtleData(): Serialization error." << std::endl;
|
||||
delete[] data ;
|
||||
delete[] msg_serialized_data ;
|
||||
return ;
|
||||
}
|
||||
|
||||
RsTurtleGenericDataItem *item = new RsTurtleGenericDataItem ;
|
||||
item->data_bytes = malloc(rssize) ;
|
||||
item->data_size = rssize ;
|
||||
memcpy(item->data_bytes,data,rssize) ;
|
||||
|
||||
delete[] data ;
|
||||
item->data_bytes = malloc(msg_serialized_rssize) ;
|
||||
item->data_size = msg_serialized_rssize ;
|
||||
memcpy(item->data_bytes,msg_serialized_data,msg_serialized_rssize) ;
|
||||
|
||||
delete[] msg_serialized_data ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
printBinaryData(item->data_bytes,item->data_size) ;
|
||||
@ -2030,7 +2192,7 @@ void p3MsgService::sendTurtleData(const std::string& hash,RsMsgItem *msgitem)
|
||||
if(it == _messenging_contacts.end())
|
||||
{
|
||||
std::cerr << "(EE) p3MsgService::sendTurtleData(): Can't find hash " << hash << " in recorded contact list." << std::endl;
|
||||
delete[] data ;
|
||||
delete[] msg_serialized_data ;
|
||||
return ;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "common/PeerDefs.h"
|
||||
#include "common/RSItemDelegate.h"
|
||||
#include "util/DateTime.h"
|
||||
#include "util/RsProtectedTimer.h"
|
||||
|
||||
#include <retroshare/rspeers.h>
|
||||
#include <retroshare/rsmsgs.h>
|
||||
@ -49,15 +50,16 @@
|
||||
#define IMAGE_STAR_OFF ":/images/star-off-16.png"
|
||||
#define IMAGE_SYSTEM ":/images/user/user_request16.png"
|
||||
|
||||
#define COLUMN_COUNT 8
|
||||
#define COLUMN_STAR 0
|
||||
#define COLUMN_ATTACHEMENTS 1
|
||||
#define COLUMN_SUBJECT 2
|
||||
#define COLUMN_UNREAD 3
|
||||
#define COLUMN_FROM 4
|
||||
#define COLUMN_DATE 5
|
||||
#define COLUMN_CONTENT 6
|
||||
#define COLUMN_TAGS 7
|
||||
#define COLUMN_SIGNATURE 5
|
||||
#define COLUMN_DATE 6
|
||||
#define COLUMN_CONTENT 7
|
||||
#define COLUMN_TAGS 8
|
||||
#define COLUMN_COUNT 9
|
||||
|
||||
#define COLUMN_DATA 0 // column for storing the userdata like msgid and srcid
|
||||
|
||||
@ -155,6 +157,7 @@ MessagesDialog::MessagesDialog(QWidget *parent)
|
||||
MessagesModel->setHeaderData(COLUMN_SUBJECT, Qt::Horizontal, tr("Subject"));
|
||||
MessagesModel->setHeaderData(COLUMN_UNREAD, Qt::Horizontal, QIcon(":/images/message-state-header.png"), Qt::DecorationRole);
|
||||
MessagesModel->setHeaderData(COLUMN_FROM, Qt::Horizontal, tr("From"));
|
||||
MessagesModel->setHeaderData(COLUMN_SIGNATURE, Qt::Horizontal, QIcon(":/images/signature.png"),Qt::DecorationRole);
|
||||
MessagesModel->setHeaderData(COLUMN_DATE, Qt::Horizontal, tr("Date"));
|
||||
MessagesModel->setHeaderData(COLUMN_TAGS, Qt::Horizontal, tr("Tags"));
|
||||
MessagesModel->setHeaderData(COLUMN_CONTENT, Qt::Horizontal, tr("Content"));
|
||||
@ -164,6 +167,7 @@ MessagesDialog::MessagesDialog(QWidget *parent)
|
||||
MessagesModel->setHeaderData(COLUMN_SUBJECT, Qt::Horizontal, tr("Click to sort by subject"), Qt::ToolTipRole);
|
||||
MessagesModel->setHeaderData(COLUMN_UNREAD, Qt::Horizontal, tr("Click to sort by read"), Qt::ToolTipRole);
|
||||
MessagesModel->setHeaderData(COLUMN_FROM, Qt::Horizontal, tr("Click to sort by from"), Qt::ToolTipRole);
|
||||
MessagesModel->setHeaderData(COLUMN_SIGNATURE, Qt::Horizontal, tr("Click to sort by signature"), Qt::ToolTipRole);
|
||||
MessagesModel->setHeaderData(COLUMN_DATE, Qt::Horizontal, tr("Click to sort by date"), Qt::ToolTipRole);
|
||||
MessagesModel->setHeaderData(COLUMN_TAGS, Qt::Horizontal, tr("Click to sort by tags"), Qt::ToolTipRole);
|
||||
MessagesModel->setHeaderData(COLUMN_STAR, Qt::Horizontal, tr("Click to sort by star"), Qt::ToolTipRole);
|
||||
@ -201,6 +205,7 @@ MessagesDialog::MessagesDialog(QWidget *parent)
|
||||
msgwheader->resizeSection (COLUMN_SUBJECT, 250);
|
||||
msgwheader->resizeSection (COLUMN_UNREAD, 16);
|
||||
msgwheader->resizeSection (COLUMN_FROM, 140);
|
||||
msgwheader->resizeSection (COLUMN_SIGNATURE, 16);
|
||||
msgwheader->resizeSection (COLUMN_DATE, 140);
|
||||
msgwheader->resizeSection (COLUMN_STAR, 16);
|
||||
|
||||
@ -240,7 +245,9 @@ MessagesDialog::MessagesDialog(QWidget *parent)
|
||||
msgwheader->setResizeMode (COLUMN_ATTACHEMENTS, QHeaderView::Fixed);
|
||||
msgwheader->setResizeMode (COLUMN_DATE, QHeaderView::Interactive);
|
||||
msgwheader->setResizeMode (COLUMN_UNREAD, QHeaderView::Fixed);
|
||||
msgwheader->setResizeMode (COLUMN_SIGNATURE, QHeaderView::Fixed);
|
||||
msgwheader->resizeSection (COLUMN_UNREAD, 24);
|
||||
msgwheader->resizeSection (COLUMN_SIGNATURE, 16);
|
||||
msgwheader->resizeSection (COLUMN_STAR, 24);
|
||||
msgwheader->setResizeMode (COLUMN_STAR, QHeaderView::Fixed);
|
||||
msgwheader->setStretchLastSection(false);
|
||||
@ -261,7 +268,7 @@ MessagesDialog::MessagesDialog(QWidget *parent)
|
||||
fillQuickView();
|
||||
|
||||
// create timer for navigation
|
||||
timer = new QTimer(this);
|
||||
timer = new RsProtectedTimer(this);
|
||||
timer->setInterval(300);
|
||||
timer->setSingleShot(true);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(updateCurrentMessage()));
|
||||
@ -1207,6 +1214,17 @@ void MessagesDialog::insertMessages()
|
||||
}
|
||||
}
|
||||
|
||||
if(it->msgflags & RS_MSG_ENCRYPTED)
|
||||
item[COLUMN_SIGNATURE]->setIcon(QIcon(":/images/blue_lock.png")) ;
|
||||
else
|
||||
if(it->msgflags & RS_MSG_SIGNED)
|
||||
if(it->msgflags & RS_MSG_SIGNATURE_CHECKS)
|
||||
item[COLUMN_SIGNATURE]->setIcon(QIcon(":/images/stock_signature_ok.png")) ;
|
||||
else
|
||||
item[COLUMN_SIGNATURE]->setIcon(QIcon(":/images/stock_signature_bad.png")) ;
|
||||
else
|
||||
item[COLUMN_SIGNATURE]->setIcon(QIcon()) ;
|
||||
|
||||
if (bInsert) {
|
||||
/* add to the list */
|
||||
QList<QStandardItem *> itemList;
|
||||
|
@ -1287,6 +1287,7 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
|
||||
return false; // Don't send with no recipient
|
||||
}
|
||||
mi.encryption_keys = _distant_peers ;
|
||||
mi.msgflags |= RS_MSG_SIGNED ;
|
||||
|
||||
if (rsMsgs->MessageSend(mi) == false) {
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user