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