Esempio n. 1
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;
}