X-Git-Url: https://vaikene.ee/gitweb/gitweb.cgi?a=blobdiff_plain;f=src%2Fapps%2FPswGen%2FCLI%2Fcli.cpp;fp=src%2Fapps%2FPswGen%2FCLI%2Fcli.cpp;h=fbc8450ebe37f2ec2ddba2170994a536587df353;hb=cdc02ee6da9c883125d5cff563bdcfcc0bf2b7b8;hp=0000000000000000000000000000000000000000;hpb=8958311b9f05fc65cdf9e528db8b4b32a94eb24a;p=evaf diff --git a/src/apps/PswGen/CLI/cli.cpp b/src/apps/PswGen/CLI/cli.cpp new file mode 100644 index 0000000..fbc8450 --- /dev/null +++ b/src/apps/PswGen/CLI/cli.cpp @@ -0,0 +1,216 @@ +/** + * @file PswGen/CLI/cli.cpp + * @brief Command line interface for the PswGen application + * @author Enar Vaikene + * + * Copyright (c) 2011 Enar Vaikene + * + * This file is part of the eVaf C++ cross-platform application development framework. + * + * This file can be used under the terms of the GNU General Public License + * version 3.0 as published by the Free Software Foundation and appearing in + * the file LICENSE included in the packaging of this file. Please review the + * the following information to ensure the GNU General Public License version + * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. + * + * Alternatively, this file may be used in accordance with the Commercial License + * Agreement provided with the Software. + */ + +#include "cli.h" +#include "version.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef Q_OS_LINUX +# include +# include +#endif +#ifdef Q_OS_WIN32 +# include +#endif + +VER_EXPORT_VERSION_INFO() +Q_EXPORT_PLUGIN2(VER_MODULE_NAME_STR, eVaf::PswGen::CLI::Module) + + +//------------------------------------------------------------------- + +using namespace eVaf; +using namespace eVaf::PswGen::CLI; + +int const Module::DefaultPasswordLength = 16; + +Module::Module() + : Plugins::iPlugin() + , mReady(false) + , mGenerator(false) + , mStorage(false) + , mEvReady(0) +{ + setObjectName(QString("%1-Module").arg(VER_MODULE_NAME_STR)); + EVAF_INFO("%s created", qPrintable(objectName())); +} + +Module::~Module() +{ + EVAF_INFO("%s destroyed", qPrintable(objectName())); +} + +bool Module::init(QString const & args) +{ + Q_UNUSED(args); + + // Get the iGenerator interface + EVAF_TEST_X((mGenerator = evafQueryInterface("iGenerator")), "No iGenerator interface"); + + // Get the optional iStorage interface + mStorage = evafQueryInterface("iStorage"); + if (!mStorage) + EVAF_WARNING("No iStorage interface"); + + // Get the iEventQueue interface and subscribe to the 'ready' event + Common::iEventQueue * eventQueue = evafQueryInterface("iEventQueue"); + EVAF_TEST_X(eventQueue, "No iEventQueue interface"); + + // Subscribe to the 'ready' event + EVAF_TEST_X((mEvReady = eventQueue->subscribeEvent(eventQueue->queryEvent(Common::iApp::EV_READY), this)), "No 'ready' event"); + + mReady = true; + + EVAF_INFO("%s initialized", qPrintable(objectName())); + + return true; +} + +void Module::done() +{ + mReady = false; + + EVAF_INFO("%s finalized", qPrintable(objectName())); +} + +bool Module::event(QEvent * e) +{ + if (e->type() == Common::Event::eVafEvent) { + Common::Event * event = static_cast(e); + + if (event->id() == mEvReady) { + + // Generate the password + generatePassword(); + + // Quit the application + Common::iApp::instance()->quit(); + } + + return false; + } + else + return Plugins::iPlugin::event(e); +} + +QString Module::readPassword() +{ + bool noEcho = false; +#ifdef Q_OS_LINUX + termios oldt; + tcgetattr(STDIN_FILENO, &oldt); + termios newt = oldt; + newt.c_lflag &= ~ECHO; + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + noEcho = true; +#elif defined Q_OS_WIN32 + HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); + DWORD mode = 0; + GetConsoleMode(hStdin, &mode); + SetConsoleMode(hStdin, mode & (~ENABLE_ECHO_INPUT)); + noEcho = true; +#endif + + QTextStream cin(stdin); + QString rval = cin.readLine(); + + if (noEcho) { + QTextStream cout(stdout); + cout << endl; + } + +#ifdef Q_OS_LINUX + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); +#elif defined Q_OS_WIN32 + SetConsoleMode(hStdin, mode); +#endif + + return rval; +} + +void Module::generatePassword() +{ + QString masterPassword; + QString appName; + int passwordLength = DefaultPasswordLength; + + // Process command-line arguments + QStringList args = QCoreApplication::arguments(); + for (int i = 0; i < args.size(); ++i) { + QStringList arg = args.at(i).simplified().split('='); + + if (QRegExp("-[-]?p(assword)?").exactMatch(arg.at(0)) && arg.size() > 1) + masterPassword = arg.at(1); + else if (QRegExp("-[-]?n(ame)?").exactMatch(arg.at(0)) && arg.size() > 1) + appName = arg.at(1); + else if (QRegExp("-[-]?l(ength)?").exactMatch(arg.at(0)) && arg.size() > 1) { + bool ok; + int t = arg.at(1).toInt(&ok); + if (!ok) { + EVAF_FATAL_ERROR("Invalid argument : %s", qPrintable(args.at(i))); + return; + } + passwordLength = t; + } + } + + QTextStream cin(stdin); + QTextStream cout(stdout); + + // Get missing arguments + while (masterPassword.isEmpty()) { + cout << tr("Master password : ") << flush; + masterPassword = readPassword(); + } + + while (appName.isEmpty()) { + cout << tr("Application name : ") << flush; + cin >> appName; + } + + // Get more arguments from the storage + QExplicitlySharedDataPointer data; + if (mStorage) { + data = mStorage->query(appName); + if (data) + passwordLength = data->length(); + } + + // Generate password + QString password = mGenerator->generatePassword(appName, masterPassword, passwordLength); + cout << "Generated password : " << password << endl; + + // Store arguments for this password + if (mStorage) { + if (!data) + data = new Storage::Data(appName, passwordLength); + mStorage->save(appName, data); + } +}