Example #1
0
   void 
   DKIMSigner::Sign(boost::shared_ptr<Message> message)
   {
     
      AnsiString senderAddress = message->GetFromAddress();
      AnsiString senderDomain = StringParser::ExtractDomain(senderAddress);

      // Check if signing is enabled for this domain.
      boost::shared_ptr<const Domain> pDomain = CacheContainer::Instance()->GetDomain(senderDomain);

      if (!pDomain || !pDomain->GetDKIMEnabled())
         return;

      LOG_DEBUG("Signing message using DKIM...");

      AnsiString selector = pDomain->GetDKIMSelector();
      AnsiString domain = pDomain->GetName();
      AnsiString privateKeyFile = pDomain->GetDKIMPrivateKeyFile();

      if (selector.IsEmpty() || privateKeyFile.IsEmpty())
      {
         ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5305, "DKIMSigner::Sign", "Either the selector or private key file was not specified.");
         return;
      }

      Canonicalization::CanonicalizeMethod headerMethod = (Canonicalization::CanonicalizeMethod) pDomain->GetDKIMHeaderCanonicalizationMethod();
      Canonicalization::CanonicalizeMethod bodyMethod = (Canonicalization::CanonicalizeMethod) pDomain->GetDKIMBodyCanonicalizationMethod();
      HashCreator::HashType algorithm = (HashCreator::HashType) pDomain->GetDKIMSigningAlgorithm();

      DKIM dkim;
      if (!dkim.Sign(message, domain, selector, privateKeyFile, algorithm, headerMethod, bodyMethod))
      {
         ErrorManager::Instance()->ReportError(ErrorManager::Medium, 5306, "DKIMSigner::Sign", "Message signing using DKIM failed.");
      }
   }
Example #2
0
   set<shared_ptr<SpamTestResult> >
   SpamTestDKIM::RunTest(shared_ptr<SpamTestData> pTestData)
   {
      shared_ptr<Message> pMessage = pTestData->GetMessageData()->GetMessage();

      set<shared_ptr<SpamTestResult> > setSpamTestResults;

      const String fileName = PersistentMessage::GetFileName(pMessage);

      DKIM dkim;
      DKIM::Result result = dkim.Verify(fileName);
      if (result == DKIM::PermFail)
      {
         // Blocked
         AntiSpamConfiguration &config= Configuration::Instance()->GetAntiSpamConfiguration();
         int iSomeScore = config.GetDKIMVerificationFailureScore();
         shared_ptr<SpamTestResult> pResult = shared_ptr<SpamTestResult>(new SpamTestResult(GetName(), SpamTestResult::Fail, iSomeScore, "Rejected by DKIM."));
         setSpamTestResults.insert(pResult);
      }
      else if (result == DKIM::Pass)
      {
         shared_ptr<SpamTestResult> pResult = shared_ptr<SpamTestResult>(new SpamTestResult(GetName(), SpamTestResult::Pass, 0, ""));
         setSpamTestResults.insert(pResult);
      }

      return setSpamTestResults;
   }
	void _SignMailTest(const SignatoryOptions& options, const std::string& mail)
	{
		std::string head;
		std::stringstream fp;
		std::stringstream fp2;
		std::string DKIMPublicKey = "v=DKIM1; p=" DKIM_PUBLICKEY "; t=s";

		fp.str(mail);
		CPPUNIT_ASSERT_NO_THROW ( head = Signatory(fp).CreateSignature(options) );

		fp2.str(head + "\r\n" + mail);
		Validatory myValidatory(fp2);

		const Validatory::SignatureList& siglist = myValidatory.GetSignatures();
		CPPUNIT_ASSERT ( siglist.size() == 1 );

		DKIM::Signature sig;
		CPPUNIT_ASSERT_NO_THROW ( myValidatory.GetSignature(siglist.begin(), sig) );

		DKIM::PublicKey pub;
		CPPUNIT_ASSERT_NO_THROW ( pub.Parse(DKIMPublicKey) );
		CPPUNIT_ASSERT_NO_THROW ( myValidatory.CheckSignature(siglist.begin(), sig, pub) );
		CPPUNIT_ASSERT_NO_THROW ( myValidatory.CheckSignature(*(siglist.begin()), sig, pub) );
	}
Example #4
0
int main(int argc, char* argv[])
{
	__progname = argv[0];

	bool validate = false;
	bool doubleDots = false;
	std::string selector;
	std::string domain;
	std::string keyfile;

	// no arguments
	if (argc < 2)
		usage(stderr, 2);

	// longopts
	static struct option longopts[] = {
		{ "help",		no_argument,		NULL,		'h'	},
		{ "doubledots",	no_argument,		NULL,		'D'	},
		{ "validate",	no_argument,		NULL,		'v'	},
		{ "selector",	required_argument,	NULL,		's'	},
		{ "domain",		required_argument,	NULL,		'd'	},
		{ "keyfile",	required_argument,	NULL,		'k'	},
		{ NULL,			0,					NULL,		0	}
	};

	// fetching arguments..
	opterr = 0;
	optind = 0;
	int ch;
	while ((ch = getopt_long(argc, argv, "hvs:d:k:D", longopts, NULL)) != -1) {
		switch (ch)
		{
			case 'D':
				doubleDots = true;
				break;
			case 'v':
				validate = true;
				break;
			case 'h':
				usage(stdout, 0);
				break;
			case 's':
				selector = optarg;
				break;
			case 'd':
				domain = optarg;
				break;
			case 'k':
				keyfile = optarg;
				break;
			case 0:
				break;
			default:
				usage(stderr, 2);
				break;
		}
	}
	argc -= optind;
	argv += optind;

	if (argc < 1)
		usage(stderr, 2);

	if (!validate && (selector.empty() || domain.empty() || keyfile.empty()))
		usage(stderr, 2);

	//  sign the message..
	if (!validate)
	{
		// readkey
		std::ifstream kfp(keyfile);
		if (!kfp) {
			fprintf(stderr, "keyfile %s could not be open\n", keyfile.c_str());
			return 1;
		}
		std::string key((std::istreambuf_iterator<char>(kfp)),
				std::istreambuf_iterator<char>());

		std::ifstream fp(argv[0]);
		try {
			printf("%s\r\n",
					Signatory(fp, doubleDots).CreateSignature(
						SignatoryOptions()
						.SetPrivateKey(key)
						.SetDomain(domain)
						.SetSelector(selector)
						.SetCanonModeHeader(DKIM::DKIM_C_RELAXED)
						.SetCanonModeBody(DKIM::DKIM_C_RELAXED)
						).c_str() );
		} catch (std::runtime_error& e) {
			fprintf(stderr, "%s\n", e.what());
			return 1;
		}

		return 0;
	}

	// validate messages (0 .. argv)
	for (int x = 0; x < argc; x++)
	{
		std::ifstream fp(argv[x]);
		Validatory mail(fp, doubleDots);

		mail.CustomDNSResolver = MyResolver;

		// first check ADSP status
		try {
			std::list<ADSP> adsp;
			mail.GetADSP(adsp);
			for (std::list<ADSP>::const_iterator i = adsp.begin(); i != adsp.end(); ++i)
			{
				printf("[%s][ADSP][%s] %s/%s\n", argv[x], i->GetDomain().c_str(), i->GetResultAsString().c_str(), i->GetReason().c_str());
			}
		} catch (DKIM::TemporaryError& e) {
			printf("[%s][ADSP] TEMPERR:%s\n", argv[x], e.what());
		} catch (DKIM::PermanentError& e) {
			printf("[%s][ADSP] PERMERR:%s\n", argv[x], e.what());
		}

		// then list all valid SDID's
		for (Validatory::SignatureList::const_iterator i = mail.GetSignatures().begin();
				i != mail.GetSignatures().end(); ++i)
		{
			DKIM::PublicKey pub;
			DKIM::Signature sig;
			try {
				mail.GetSignature(i, sig);
				mail.GetPublicKey(sig, pub);
				mail.CheckSignature(i, sig, pub);
				printf("[%s][%s] OK\n", argv[x], sig.GetDomain().c_str());
			} catch (DKIM::TemporaryError& e) {
				printf("[%s][%s] TEMPERR:%s\n", argv[x], sig.GetDomain().c_str(), e.what());
			} catch (DKIM::PermanentError& e) {
				if (pub.SoftFail())
					printf("[%s][%s] SOFT:%s\n", argv[x], sig.GetDomain().c_str(), e.what());
				else
					printf("[%s][%s] = %s\n", argv[x], sig.GetDomain().c_str(), e.what());
			}
		}
	}

	return 0;
}