More work on GXS mail subservices

This commit is contained in:
Gioacchino Mazzurco 2017-02-07 20:33:06 +01:00
parent 1f1f4ded02
commit 4daca00359
2 changed files with 120 additions and 85 deletions

View File

@ -149,6 +149,13 @@ bool p3GxsMails::sendMail( GxsMailsClient::GxsMailSubServices service,
return true; return true;
} }
void p3GxsMails::registerGxsMailsClient(
GxsMailsClient::GxsMailSubServices serviceType, GxsMailsClient* service)
{
RS_STACK_MUTEX(servClientsMutex);
servClients[serviceType] = service;
}
void p3GxsMails::handleResponse(uint32_t token, uint32_t req_type) void p3GxsMails::handleResponse(uint32_t token, uint32_t req_type)
{ {
@ -239,81 +246,7 @@ void p3GxsMails::handleResponse(uint32_t token, uint32_t req_type)
break; break;
} }
handleEcryptedMail(msg);
std::cout << "p3GxsMails::handleResponse(...) "
<< "GXS_MAIL_SUBTYPE_MAIL got from: "
<< msg->meta.mAuthorId
<< " recipientsHint: "
<< msg->recipientsHint << " cryptoType: "
<< (uint32_t)msg->cryptoType
<< " payload size: " << msg->payload.size()
<< std::endl;
std::set<RsGxsId> decryptIds;
std::list<RsGxsId> ownIds;
idService.getOwnIds(ownIds);
for(auto it = ownIds.begin(); it != ownIds.end(); ++it)
if(msg->maybeRecipient(*it)) decryptIds.insert(*it);
if(decryptIds.empty())
{
std::cout << "p3GxsMails::handleResponse(...) "
<< "GXS_MAIL_SUBTYPE_MAIL hint match none"
<< " of our own ids" << msg->recipientsHint
<< std::endl;
break;
}
std::cout << "p3GxsMails::handleResponse(...) "
<< "GXS_MAIL_SUBTYPE_MAIL hint: "
<< msg->recipientsHint
<< " match with own ids: ";
for(auto it=decryptIds.begin(); it != decryptIds.end(); ++it)
std::cout << *it;
std::cout << std::endl;
switch (msg->cryptoType)
{
case RsGxsMailBaseItem::CLEAR_TEXT:
{
uint16_t csri = 0;
uint32_t off;
getRawUInt16(&msg->payload[0], 2, &off, &csri);
std::string str(reinterpret_cast<const char*>(&msg->payload[2]), msg->payload.size()-2);
std::cout << "service: " << csri
<< " got CLEAR_TEXT message: "
<< str << std::endl;
break;
}
case RsGxsMailBaseItem::RSA:
{
uint8_t* decrypted_data = NULL;
uint32_t decrypted_data_size = 0;
uint32_t decryption_error;
if( idService.decryptData(
&msg->payload[0],
msg->payload.size(), decrypted_data,
decrypted_data_size, decryptIds,
decryption_error ) )
{
uint16_t csri = *reinterpret_cast<uint16_t*>(decrypted_data);
std::string str(reinterpret_cast<char const*>(decrypted_data+2), decrypted_data_size-2);
std::cout << "service: " << csri
<< " got RSA message: "
<< str << std::endl;
}
else std::cout << "p3GxsMails::handleResponse(...) "
<< "GXS_MAIL_SUBTYPE_MAIL RSA decryption"
<< " failed" << std::endl;
free(decrypted_data);
break;
}
default:
std::cout << "Unknown encryption type:"
<< msg->cryptoType << std::endl;
break;
}
break; break;
} }
default: default:
@ -421,3 +354,93 @@ bool p3GxsMails::requestGroupsData(const std::list<RsGxsGroupId>* groupIds)
return true; return true;
} }
bool p3GxsMails::handleEcryptedMail(RsGxsMailItem* mail)
{
std::set<RsGxsId> decryptIds;
std::list<RsGxsId> ownIds;
idService.getOwnIds(ownIds);
for(auto it = ownIds.begin(); it != ownIds.end(); ++it)
if(mail->maybeRecipient(*it)) decryptIds.insert(*it);
// Hint match none of our own ids
if(decryptIds.empty()) goto hFail;
for(auto it=decryptIds.begin(); it != decryptIds.end(); ++it)
std::cout << *it;
std::cout << std::endl;
switch (mail->cryptoType)
{
case RsGxsMailBaseItem::CLEAR_TEXT:
{
uint16_t csri;
uint32_t off = 0;
getRawUInt16(&mail->payload[0], 2, &off, &csri);
std::cerr << "service: " << csri << " got CLEAR_TEXT mail!"
<< std::endl;
if( !dispatchDecryptedMail( mail, &mail->payload[2],
mail->payload.size()-2 ) )
goto hFail;
break;
}
case RsGxsMailBaseItem::RSA:
{
uint8_t* decrypted_data = NULL;
uint32_t decrypted_data_size = 0;
uint32_t decryption_error;
bool ok = idService.decryptData( &mail->payload[0],
mail->payload.size(), decrypted_data,
decrypted_data_size, decryptIds,
decryption_error );
ok = ok && dispatchDecryptedMail( mail, decrypted_data,
decrypted_data_size );
if(!ok)
{
std::cout << "p3GxsMails::handleEcryptedMail(...) "
<< "RSA decryption failed" << std::endl;
free(decrypted_data);
goto hFail;
}
break;
}
default:
std::cout << "Unknown encryption type:"
<< mail->cryptoType << std::endl;
goto hFail;
}
return true;
hFail:
delete mail;
return false;
}
bool p3GxsMails::dispatchDecryptedMail( RsGxsMailItem* received_msg,
uint8_t* decrypted_data,
uint32_t decrypted_data_size )
{
uint16_t csri;
uint32_t off;
getRawUInt16(decrypted_data, decrypted_data_size, &off, &csri);
GxsMailsClient::GxsMailSubServices rsrvc;
rsrvc = static_cast<GxsMailsClient::GxsMailSubServices>(csri);
GxsMailsClient* reecipientService = NULL;
{
RS_STACK_MUTEX(servClientsMutex);
reecipientService = servClients[rsrvc];
}
if(reecipientService)
return reecipientService->receiveGxsMail( received_msg,
&decrypted_data[2],
decrypted_data_size-2 );
else
{
std::cerr << "p3GxsMails::dispatchReceivedMail(...) "
<< "got message for unknown service: "
<< csri << std::endl;
return false;
}
}

View File

@ -41,14 +41,16 @@ struct GxsMailsClient
/** /**
* This will be called by p3GxsMails to dispatch mails to the subservice * This will be called by p3GxsMails to dispatch mails to the subservice
* @param destinationId * @param originalMessage message as received from GXS backend (encrypted)
* @param signingKey * GxsMailsClient take ownership of it ( aka should take free/delete it
* @param data * when not needed anymore )
* @param dataSize * @param data buffer containing the decrypted data
* GxsMailsClient take ownership of it ( aka should take free/delete it
* when not needed anymore )
* @param dataSize size of the buffer
* @return true if dispatching goes fine, false otherwise * @return true if dispatching goes fine, false otherwise
*/ */
virtual bool receiveGxsMail( const RsGxsId& destinationId, virtual bool receiveGxsMail( RsGxsMailItem* originalMessage,
const RsGxsId& signingKey,
uint8_t* data, uint32_t dataSize ) = 0; uint8_t* data, uint32_t dataSize ) = 0;
}; };
@ -60,7 +62,8 @@ struct p3GxsMails : RsGenExchange, GxsTokenQueue
RS_SERVICE_TYPE_GXS_MAIL, &identities, RS_SERVICE_TYPE_GXS_MAIL, &identities,
AuthenPolicy(), AuthenPolicy(),
RS_GXS_DEFAULT_MSG_STORE_PERIOD ), // TODO: Discuss with Cyril about this RS_GXS_DEFAULT_MSG_STORE_PERIOD ), // TODO: Discuss with Cyril about this
GxsTokenQueue(this), idService(identities) {} GxsTokenQueue(this), idService(identities),
servClientsMutex("p3GxsMails client services map mutex") {}
/** /**
* Send an email to recipient, in the process author of the email is * Send an email to recipient, in the process author of the email is
@ -94,11 +97,9 @@ struct p3GxsMails : RsGenExchange, GxsTokenQueue
/** /**
* Register a client service to p3GxsMails to receive mails via * Register a client service to p3GxsMails to receive mails via
* GxsMailsClient::receiveGxsMail(...) callback * GxsMailsClient::receiveGxsMail(...) callback
* This is NOT thread safe!
*/ */
void registerGxsMailsClient( GxsMailsClient::GxsMailSubServices serviceType, void registerGxsMailsClient( GxsMailsClient::GxsMailSubServices serviceType,
GxsMailsClient* service ) GxsMailsClient* service );
{ servClients[serviceType] = service; }
/** /**
* @see GxsTokenQueue::handleResponse(uint32_t token, uint32_t req_type) * @see GxsTokenQueue::handleResponse(uint32_t token, uint32_t req_type)
@ -141,6 +142,8 @@ private:
/// Stores pointers to client services to notify them about new mails /// Stores pointers to client services to notify them about new mails
std::map<GxsMailsClient::GxsMailSubServices, GxsMailsClient*> servClients; std::map<GxsMailsClient::GxsMailSubServices, GxsMailsClient*> servClients;
RsMutex servClientsMutex;
/// Request groups list to GXS backend. Async method. /// Request groups list to GXS backend. Async method.
bool requestGroupsData(const std::list<RsGxsGroupId>* groupIds = NULL); bool requestGroupsData(const std::list<RsGxsGroupId>* groupIds = NULL);
@ -169,5 +172,14 @@ private:
/// @return true if has passed more then interval seconds time since timeStamp /// @return true if has passed more then interval seconds time since timeStamp
bool static inline olderThen(time_t timeStamp, int32_t interval) bool static inline olderThen(time_t timeStamp, int32_t interval)
{ return (timeStamp + interval) < time(NULL); } { return (timeStamp + interval) < time(NULL); }
/// Decrypt email content and pass it to dispatchDecryptedMail(...)
bool handleEcryptedMail(RsGxsMailItem* mail);
/// Dispatch the message to the recipient service
bool dispatchDecryptedMail( RsGxsMailItem* received_msg,
uint8_t* decrypted_data,
uint32_t decrypted_data_size );
}; };