Example #1
0
		void EMailImapService::returningMailCheck(vmime::ref<vmime::net::message> &msg)
		{
			dtn::data::BundleID bid;

			bool bidFound = false;

			std::string s;
			vmime::utility::outputStreamStringAdapter out(s);

			vmime::messageParser mp(msg->getParsedMessage());

			for(int i = 0; i < mp.getTextPartCount(); ++i)
			{
				s.clear();
				mp.getTextPartAt(i)->getText()->extract(out);

				try {
					bid = extractBID(s);
					bidFound = true;
					break;
				}catch(InvalidConversion&) {}
			}

			if(!bidFound)
			{
				for(int i = 0; i < mp.getAttachmentCount(); ++i)
				{
					s.clear();
					mp.getAttachmentAt(i)->getData()->extract(out);

					try {
						bid = extractBID(s);
						bidFound = true;
						break;
					}catch(InvalidConversion&) {}
				}
			}

			{
				ibrcommon::Mutex l(_processedTasksMutex);
				for(std::list<EMailSmtpService::Task*>::iterator iter = _processedTasks.begin(); iter != _processedTasks.end(); ++iter)
				{
					if((*iter)->getJob().getBundle() == bid)
					{
						dtn::routing::RequeueBundleEvent::raise((*iter)->getNode().getEID(), bid, dtn::core::Node::CONN_EMAIL);
						_processedTasks.erase(iter);
						break;
					}
				}
			}

			if(!bidFound)
				throw BidNotFound("Found no bundle ID");
		}
Example #2
0
		void EMailImapService::generateBundle(vmime::ref<vmime::net::message> &msg)
		{

			// Create new Bundle
			dtn::data::Bundle newBundle;

			// Clear all blocks
			newBundle.clear();

			// Get header of mail
			vmime::ref<const vmime::header> header = msg->getHeader();
			std::string mailID = " (ID: " + msg->getUniqueId() + ")";

			// Check EMailCL version
			try {
				int version = toInt(header->findField("Bundle-EMailCL-Version")->getValue()->generate());
				if(version != 1)
					throw IMAPException("Wrong EMailCL version found in mail" + mailID);
			}catch(vmime::exceptions::no_such_field&) {
				throw IMAPException("Field \"Bundle-EMailCL-Version\" not found in mail" + mailID);
			}catch(InvalidConversion&) {
				throw IMAPException("Field \"Bundle-EMailCL-Version\" wrong formatted in mail" + mailID);
			}

			try {
				newBundle.procflags = toInt(header->findField("Bundle-Flags")->getValue()->generate());
				newBundle.destination = header->findField("Bundle-Destination")->getValue()->generate();
				newBundle.source = dtn::data::EID(header->findField("Bundle-Source")->getValue()->generate());
				newBundle.reportto = header->findField("Bundle-Report-To")->getValue()->generate();
				newBundle.custodian = header->findField("Bundle-Custodian")->getValue()->generate();
				newBundle.timestamp = toInt(header->findField("Bundle-Creation-Time")->getValue()->generate());
				newBundle.sequencenumber = toInt(header->findField("Bundle-Sequence-Number")->getValue()->generate());
				newBundle.lifetime = toInt(header->findField("Bundle-Lifetime")->getValue()->generate());
			}catch(vmime::exceptions::no_such_field&) {
				throw IMAPException("Missing bundle headers in mail" + mailID);
			}catch(InvalidConversion&) {
				throw IMAPException("Wrong formatted bundle headers in mail" + mailID);
			}

			// If bundle is a fragment both fields need to be set
			try {
				newBundle.fragmentoffset = toInt(header->findField("Bundle-Fragment-Offset")->getValue()->generate());
				newBundle.appdatalength = toInt(header->findField("Bundle-Total-Application-Data-Unit-Length")->getValue()->generate());
			}catch(vmime::exceptions::no_such_field&) {
				newBundle.fragmentoffset = 0;
				newBundle.appdatalength = 0;
			}catch(InvalidConversion&) {
				throw IMAPException("Wrong formatted fragment offset in mail" + mailID);
			}

			//Check if bundle is already in the storage
			try {
				if(dtn::core::BundleCore::getInstance().getRouter().isKnown(newBundle))
					throw IMAPException("Bundle in mail" + mailID + " already processed");
			} catch (dtn::storage::NoBundleFoundException&) {
				// Go ahead
			}

			// Validate the primary block
			try {
				dtn::core::BundleCore::getInstance().validate((dtn::data::PrimaryBlock)newBundle);
			}catch(dtn::data::Validator::RejectedException&) {
				throw IMAPException("Bundle in mail" + mailID + " was rejected by validator");
			}

			// Get names of additional blocks
			std::vector<vmime::ref<vmime::headerField> > additionalBlocks =
					header.constCast<vmime::header>()->findAllFields("Bundle-Additional-Block");
			std::vector<std::string> additionalBlockNames;
			for(std::vector<vmime::ref<vmime::headerField> >::iterator it = additionalBlocks.begin();
					it != additionalBlocks.end(); ++it)
			{
				additionalBlockNames.push_back((*it)->getValue()->generate());
			}

			// Get all attachments
			std::vector<vmime::ref<const vmime::attachment> > attachments =
					vmime::attachmentHelper::findAttachmentsInMessage(msg->getParsedMessage());

			// Extract payload block info
			size_t payloadFlags;
			std::string payloadName;
			try {
				payloadFlags = toInt(header->findField("Bundle-Payload-Flags")->getValue()->generate());
				// Payload length will be calculated automatically
				//length = toInt(header->findField("Bundle-Payload-Block-Length")->getValue()->generate());
				payloadName = header->findField("Bundle-Payload-Data-Name")->getValue()->generate();
			}catch(vmime::exceptions::no_such_field&) {
				// No payload block there
			}catch(InvalidConversion&) {
				throw IMAPException("Wrong formatted payload flags in mail" + mailID);
			}

			// Create new bundle builder
			dtn::data::BundleBuilder builder(newBundle);

			// Download attachments
			for(std::vector<vmime::ref<const vmime::attachment> >::iterator it = attachments.begin(); it != attachments.end(); ++it)
			{
				if((*it)->getName().getBuffer() == payloadName && !payloadName.empty()) {
					dtn::data::PayloadBlock &pb = newBundle.push_back<dtn::data::PayloadBlock>();
					// Set data
					ibrcommon::BLOB::Reference ref = pb.getBLOB();
					ibrcommon::BLOB::iostream payloadData = ref.iostream();
					vmime::utility::outputStreamAdapter data((*payloadData));
					(*it)->getData()->extract(data);
					// Set flags
					setProcFlags(pb, payloadFlags);
					continue;
				}

				// If current attachment name is contained in additional attachment list
				if(std::find(additionalBlockNames.begin(), additionalBlockNames.end(), (*it)->getName().getBuffer()) != additionalBlockNames.end())
				{
					// Search for the block type
					block_t blockType;
					try {
						blockType = toInt((*it)->getHeader()->findField("Block-Type")->getValue()->generate());
					}catch(vmime::exceptions::no_such_field&) {
						throw IMAPException("Block type not found in attachment of mail" + mailID);
					}

					// Search for processing flags
					size_t flags;
					try {
						flags = toInt((*it)->getHeader()->findField("Block-Processing-Flags")->getValue()->generate());
					}catch(vmime::exceptions::no_such_field&) {
						throw IMAPException("Missing block processing flags in extension attachment of mail" + mailID);
					}catch(InvalidConversion&) {
						throw IMAPException("Wrong formatted processing flags in extension attachment of mail" + mailID);
					}

					// Create a block object
					dtn::data::Block &block = builder.insert(blockType, flags);

					// Add EIDs
					try {
						addEIDList(block, (*it));
					}catch(InvalidConversion&) {
						throw IMAPException("Wrong formatted EID list in extension attachment of mail" + mailID);
					}

					// Get payload of current block
					std::stringstream ss;
					vmime::utility::outputStreamAdapter data(ss);
					(*it)->getData()->extract(data);

					block.deserialize(ss, ss.str().length());
				}
			}

			// Validate whole bundle
			try {
				dtn::core::BundleCore::getInstance().validate(newBundle);
			}catch(dtn::data::Validator::RejectedException&) {
				throw IMAPException("Bundle in mail" + mailID + " was rejected by validator");
			}

			// create a filter context
			dtn::core::FilterContext context;
			context.setProtocol(dtn::core::Node::CONN_EMAIL);

			// push bundle through the filter routines
			context.setBundle(newBundle);
			BundleFilter::ACTION ret = dtn::core::BundleCore::getInstance().filter(dtn::core::BundleFilter::INPUT, context, newBundle);

			if (ret == BundleFilter::ACCEPT)
			{
				// Raise default bundle received event
				dtn::net::BundleReceivedEvent::raise(newBundle.source, newBundle, false);
			}
		}