summaryrefslogblamecommitdiffstats
path: root/Compass.cpp
blob: dd0bbaf5a00ec52e5da0756b7676e891bf8498f0 (plain) (tree)

















































































































                                                                                              






































































































                                                                                                                                                                             
                                                       





















                                                                                                                          
                                                       




                        
                                                       







                                                                                                        
                                                       























                                                                                                          
                                                       




















                                                                                                                                               
                                                       

















                                                                                        
                                                       














                                                                               
                                                       












                                                                             
                                                       

























                                                                                                            
                                                       





























                                                                                                            
#include "Compass.h"

Compass::Compass() {
}

Compass::~Compass() {
}

void Compass::perform(int argc, char* argv[]) {
	// Figure out action
	if (argc < 2) {
		std::cerr << ERR_NO_ACTION << std::endl;
		std::cout << "Run 'compass help' for more information." << std::endl;
		return;
	}

	try {
		std::string action(argv[1]);

		// Need Help?
		if (action == "help") {
			initNoArgs(argc, argv);
			help();
		}

		// Supported Actions
		else if (action == "initialize") {
			initNoArgs(argc, argv);
			initialize();
		}

		else if (action == "create") {
			std::string service = initOneArg(argc, argv);
			create(service);
		}

		else if (action == "walk" && ALLOW_WALK) {
			initNoArgs(argc, argv);
			walk();
		}

		else if (action == "rekey") {
			initNoArgs(argc, argv);
			rekey();
		}

		else if (action == "get") {
			std::string service = initOneArg(argc, argv);
			get(service);
		}

		else if (action == "delete") {
			std::string service = initOneArg(argc, argv);
			_delete(service);
		}

		else if (action == "show") {
			initNoArgs(argc, argv);
			show("", false);
		}

		else if (action == "show1") {
			std::string service = initOneArg(argc, argv);
			show(service, false);
		}

		else if (action == "showlike") {
			std::string service = initOneArg(argc, argv);
			show(service, true);
		}

		else if (action == "random") {
			initNoArgs(argc, argv);
			random();
		}

		else if (action == "markreset") {
			initNoArgs(argc, argv);
			markReset("");
		}

		else if (action == "markreset1") {
			std::string service = initOneArg(argc, argv);
			markReset(service);
		}

		else if (action == "checkreset") {
			initNoArgs(argc, argv);
			checkReset("");
		}

		else if (action == "checkreset1") {
			std::string service = initOneArg(argc, argv);
			checkReset(service);
		}

		else if (action == "ruser") {
			std::string service = initOneArg(argc, argv);
			ruser(service);
		}

		else if (action == "rpass") {
			std::string service = initOneArg(argc, argv);
			rpass(service);
		}

		else {
			std::cerr << ERR_INVALID_ACTION << std::endl;
			std::cout << "Run 'compass help' for more information." << std::endl;
		}
	}
	catch (const int e) {
		std::cerr << ERR_GENERIC << std::endl;
	}
	catch (const double e) {
		std::cerr << ERR_INPUT << std::endl;
	}
	catch (const bool e) {
		// do nothing (message was produced by called function)
	}
}

void Compass::initNoArgs(int argc, char* argv[]) {
	opt.parseArgv(2, argc, argv);
}

std::string Compass::initOneArg(int argc, char* argv[]) {
	if (argc < 3) {
		std::cerr << ERR_REQ_PARAMS_MISSING << std::endl;
		throw false;
	}

	std::string arg(argv[2]);
	opt.checkString(arg);
	opt.parseArgv(3, argc, argv);
	return arg;
}

void Compass::showResult(Credential c) {
	std::cout << "Username is: " << c.username << std::endl;

	if (opt.pp)
		std::cout << "Password is: " << c.password << std::endl;
	else
		pasteClipboard(c.password, !opt.cc, false);
}

void Compass::pasteClipboard(std::string text, bool clean, bool recur) {
	#ifdef WIN32

		if (OpenClipboard(NULL)) {
			HGLOBAL clipbuffer;
			char* buffer;
			EmptyClipboard();
			const char* source = text.c_str();
			clipbuffer = GlobalAlloc(GMEM_DDESHARE, strlen(source) + 1);
			buffer = (char*)GlobalLock(clipbuffer);
			strcpy(buffer, LPCSTR(source));
			GlobalUnlock(clipbuffer);
			SetClipboardData(CF_TEXT, clipbuffer);
			CloseClipboard();
			std::cout << MSG_CLIPBOARD << std::endl;
		}
		else {
			std::cerr << ERR_CLIPBOARD << std::endl;
		}

	#else
	#ifdef __APPLE__

		std::string sink = "pbcopy";

	#else

		std::string sink = "xclip -selection c";

	#endif // __APPLE__

		// Mac/Linux procedure
		std::string cmd = "printf %s '" + text + "' | " + sink;
		system(cmd.c_str());
		if (!recur) std::cout << MSG_CLIPBOARD << std::endl;
		else exit(EXIT_SUCCESS);

		// Cleanup
		if (clean) {
			pid_t pid = fork();
			if (pid == 0) {
				usleep(SECONDS_PSWD_CLEANUP * 1000000);
				pasteClipboard(CLEAN_STRING, clean, true);
			}
			else if (pid < 0) {
				std::cerr << WARN_CANT_CLEANUP << std::endl;
			}
		}

	#endif // WIN32

	if (!clean) std::cout << WARN_WONT_CLEANUP << std::endl;
}

void Compass::help() {
	Help h;
	h.dispGeneral();
}

void Compass::initialize() {
	std::cout << "WARNING: This will destroy the keychain (if one exists) at '" << opt.dr << "'" << std::endl;
	std::cout << "You may still abort this action by pressing CTRL-C now. If you wish to procede, create a new master password for your keychain below..." << std::endl;
	std::cout << std::endl;

	Keychain* kc = Keychain::newKeychain(opt.dr);
	kc->saveKeychain();
	delete kc;
}

void Compass::create(std::string service) {
	Keychain* kc = Keychain::loadKeychain(opt.dr);
	Credential c;

	if (opt.user != "" && opt.pass != "")
		c = kc->create(service, opt.user, opt.pass);

	else if (opt.user != "")
		c = kc->create(service, opt.user, opt.getPasswordSpec());

	else if (opt.pass != "")
		c = kc->create(service, opt.pass);

	else
		c = kc->create(service, opt.getPasswordSpec());

	std::cout << "Created new credential for " << service << "(" << kc->getServiceCount(service) << ")" << std::endl;
	showResult(c);

	kc->saveKeychain();
	delete kc;
}

void Compass::walk() {
	Keychain* kc = Keychain::loadKeychain(opt.dr);
	kc->walk();
	delete kc;
}

void Compass::rekey() {
	Keychain* kc = Keychain::loadKeychain(opt.dr);
	Cryptor::rekey();

	std::cout << "Enter a new master password for your keychain... (CTRL-C to abort)" << std::endl;
	kc->saveKeychain();
	delete kc;
}

void Compass::get(std::string service) {
	Keychain* kc = Keychain::loadKeychain(opt.dr);
	Credential c;

	if (opt.cn != -1)
		c = kc->get(service, opt.cn);

	else if (opt.user != "")
		c = kc->get(service, opt.user);

	else
		c = kc->get(service);

	std::cout << "Found from " << service << "(" << kc->getServiceCount(service) << ")" << std::endl;
	showResult(c);

	if (c.reset) {
		std::cout << "************************************************" << std::endl;
		std::cout << "* Notice: this credential is marked for reset! *" << std::endl;
		std::cout << "************************************************" << std::endl;
	}

	delete kc;
}

void Compass::_delete(std::string service) {
	Keychain* kc = Keychain::loadKeychain(opt.dr);
	bool b;

	if (opt.cn != -1)
		b = kc->_delete(service, opt.cn);

	else if (opt.user != "")
		b = kc->_delete(service, opt.user);

	else
		b = kc->_delete(service);

	if (b)
		std::cout << service << "(" << kc->getServiceCount(service) << ") has been fully removed from the keychain." << std::endl;
	else
		std::cout << service << "(" << kc->getServiceCount(service) << ") has been partially removed from the keychain." << std::endl;

	kc->saveKeychain();
	delete kc;
}

void Compass::show(std::string service, bool like) {
	Keychain* kc = Keychain::loadKeychain(opt.dr);

	if (service == "")
		kc->show();

	else if (like)
		kc->showlike(service);

	else
		kc->show1(service);

	delete kc;
}

void Compass::random() {
	std::cout << Cryptor::createRandomPassword(opt.getPasswordSpec()) << std::endl;
}

void Compass::markReset(std::string service) {
	Keychain* kc = Keychain::loadKeychain(opt.dr);
	int i;

	if (service == "")
		i = kc->markResetAll();

	else
		i = kc->markResetOne(service);

	std::cout << "Marked " << i << " credentials for reset." << std::endl;

	kc->saveKeychain();
	delete kc;
}

void Compass::checkReset(std::string service) {
	Keychain* kc = Keychain::loadKeychain(opt.dr);
	int i;

	if (service == "")
		i = kc->checkResetAll();

	else
		i = kc->checkResetOne(service);

	std::cout << i << " credentials are marked for reset." << std::endl;
	delete kc;
}

void Compass::ruser(std::string service) {
	Keychain* kc = Keychain::loadKeychain(opt.dr);
	Credential c;

	if (opt.user == "") {
		if (opt.cn == -1)
			c = kc->ruser(service);

		else
			c = kc->ruser(service, opt.cn);
	}

	else {
		if (opt.cn == -1)
			c = kc->ruser(service, opt.user);

		else
			c = kc->ruser(service, opt.user, opt.cn);
	}

	std::cout << "Altered from " << service << "(" << kc->getServiceCount(service) << ")" << std::endl;
	showResult(c);

	kc->saveKeychain();
	delete kc;
}

void Compass::rpass(std::string service) {
	Keychain* kc = Keychain::loadKeychain(opt.dr);
	Credential c;

	if (opt.pass == "") {
		if (opt.user == "" && opt.cn == -1)
			c = kc->rpass(service, opt.getPasswordSpec());

		else if (opt.cn != -1)
			c = kc->rpass(service, opt.getPasswordSpec(), opt.cn);

		else
			c = kc->rpass(service, opt.getPasswordSpec(), opt.user);
	}

	else {
		if (opt.user == "" && opt.cn == -1)
			c = kc->rpass(service, opt.pass);

		else if (opt.cn != -1)
			c = kc->rpass(service, opt.pass, opt.cn);

		else
			c = kc->rpass(service, opt.pass, opt.user);
	}

	std::cout << "Altered from " << service << "(" << kc->getServiceCount(service) << ")" << std::endl;
	showResult(c);

	kc->saveKeychain();
	delete kc;
}