#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; }