diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index 225ce47dc..92277811b 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -20,6 +20,8 @@ set(cli_SOURCES Clip.h Command.cpp Command.h + Diceware.cpp + Diceware.h Edit.cpp Edit.h Estimate.cpp @@ -32,6 +34,8 @@ set(cli_SOURCES Locate.h Merge.cpp Merge.h + PassGen.cpp + PassGen.h Remove.cpp Remove.h Show.cpp diff --git a/src/cli/Command.cpp b/src/cli/Command.cpp index 6ec07b7af..a9a53449e 100644 --- a/src/cli/Command.cpp +++ b/src/cli/Command.cpp @@ -24,12 +24,14 @@ #include "Add.h" #include "Clip.h" +#include "Diceware.h" #include "Edit.h" #include "Estimate.h" #include "Extract.h" #include "List.h" #include "Locate.h" #include "Merge.h" +#include "PassGen.h" #include "Remove.h" #include "Show.h" @@ -61,12 +63,14 @@ void populateCommands() if (commands.isEmpty()) { commands.insert(QString("add"), new Add()); commands.insert(QString("clip"), new Clip()); + commands.insert(QString("diceware"), new Diceware()); commands.insert(QString("edit"), new Edit()); commands.insert(QString("estimate"), new Estimate()); commands.insert(QString("extract"), new Extract()); commands.insert(QString("locate"), new Locate()); commands.insert(QString("ls"), new List()); commands.insert(QString("merge"), new Merge()); + commands.insert(QString("passgen"), new PassGen()); commands.insert(QString("rm"), new Remove()); commands.insert(QString("show"), new Show()); } diff --git a/src/cli/Diceware.cpp b/src/cli/Diceware.cpp new file mode 100644 index 000000000..ddc8f43a5 --- /dev/null +++ b/src/cli/Diceware.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2018 KeePassXC Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 or (at your option) + * version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "Diceware.h" + +#include +#include + +#include "core/PassphraseGenerator.h" + +Diceware::Diceware() +{ + this->name = QString("diceware"); + this->description = QObject::tr("Generate a new random password."); +} + +Diceware::~Diceware() +{ +} + +int Diceware::execute(QStringList arguments) +{ + QTextStream inputTextStream(stdin, QIODevice::ReadOnly); + QTextStream outputTextStream(stdout, QIODevice::WriteOnly); + + QCommandLineParser parser; + parser.setApplicationDescription(this->description); + QCommandLineOption wordlistFile(QStringList() << "w" + << "wordlist", + QObject::tr("Wordlist fot the diceware generator.\n[Default: EFF English]"), + QObject::tr("path")); + parser.addOption(wordlistFile); + parser.addPositionalArgument("words", QObject::tr("Word count for the diceware generator.")); + parser.process(arguments); + + const QStringList args = parser.positionalArguments(); + if (args.size() != 1) { + outputTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli diceware"); + return EXIT_FAILURE; + } + + PassphraseGenerator dicewareGenerator; + + int words = args.at(0).toInt(); + dicewareGenerator.setWordCount(words); + + if (!parser.value(wordlistFile).isEmpty()) { + dicewareGenerator.setWordList(parser.value(wordlistFile)); + } else { + dicewareGenerator.setDefaultWordList(); + } + + if (!dicewareGenerator.isValid()) { + outputTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli passgen"); + return EXIT_FAILURE; + } + + QString password = dicewareGenerator.generatePassphrase(); + outputTextStream << password << endl; + + return EXIT_SUCCESS; +} diff --git a/src/cli/Diceware.h b/src/cli/Diceware.h new file mode 100644 index 000000000..b6d71b6c6 --- /dev/null +++ b/src/cli/Diceware.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2018 KeePassXC Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 or (at your option) + * version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef KEEPASSXC_DICEWARE_H +#define KEEPASSXC_DICEWARE_H + +#include "Command.h" + +class Diceware : public Command +{ +public: + Diceware(); + ~Diceware(); + int execute(QStringList arguments); +}; + +#endif // KEEPASSXC_DICEWARE_H diff --git a/src/cli/PassGen.cpp b/src/cli/PassGen.cpp new file mode 100644 index 000000000..036f08db9 --- /dev/null +++ b/src/cli/PassGen.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2018 KeePassXC Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 or (at your option) + * version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "PassGen.h" + +#include +#include + +#include "core/PasswordGenerator.h" + +PassGen::PassGen() +{ + this->name = QString("passgen"); + this->description = QObject::tr("Generate a new random password."); +} + +PassGen::~PassGen() +{ +} + +int PassGen::execute(QStringList arguments) +{ + QTextStream inputTextStream(stdin, QIODevice::ReadOnly); + QTextStream outputTextStream(stdout, QIODevice::WriteOnly); + + QCommandLineParser parser; + parser.setApplicationDescription(this->description); + QCommandLineOption lower(QStringList() << "l", + QObject::tr("Use lowercase in the generated password.")); + parser.addOption(lower); + QCommandLineOption upper(QStringList() << "u", + QObject::tr("Use uppercase in the generated password.")); + parser.addOption(upper); + QCommandLineOption numeric(QStringList() << "n", + QObject::tr("Use numbers in the generated password.")); + parser.addOption(numeric); + QCommandLineOption special(QStringList() << "s", + QObject::tr("Use special characters in the generated password.")); + parser.addOption(special); + QCommandLineOption extended(QStringList() << "e", + QObject::tr("Use extended ascii in the generated password.")); + parser.addOption(extended); + parser.addPositionalArgument("length", QObject::tr("Length of the generated password.")); + parser.process(arguments); + + const QStringList args = parser.positionalArguments(); + if (args.size() != 1) { + outputTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli passgen"); + return EXIT_FAILURE; + } + + PasswordGenerator passwordGenerator; + + int length = args.at(0).toInt(); + passwordGenerator.setLength(length); + + PasswordGenerator::CharClasses classes = 0x0; + + if (parser.isSet(lower)) { + classes |= PasswordGenerator::LowerLetters; + } + if (parser.isSet(upper)) { + classes |= PasswordGenerator::UpperLetters; + } + if (parser.isSet(numeric)) { + classes |= PasswordGenerator::Numbers; + } + if (parser.isSet(special)) { + classes |= PasswordGenerator::SpecialCharacters; + } + if (parser.isSet(extended)) { + classes |= PasswordGenerator::EASCII; + } + + if (classes == 0x0) { + passwordGenerator.setCharClasses(PasswordGenerator::LowerLetters | PasswordGenerator::UpperLetters | + PasswordGenerator::Numbers); + } else { + passwordGenerator.setCharClasses(classes); + } + + if (!passwordGenerator.isValid()) { + outputTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli passgen"); + return EXIT_FAILURE; + } + + QString password = passwordGenerator.generatePassword(); + outputTextStream << password << endl; + + return EXIT_SUCCESS; +} diff --git a/src/cli/PassGen.h b/src/cli/PassGen.h new file mode 100644 index 000000000..5c0b33aeb --- /dev/null +++ b/src/cli/PassGen.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2017 KeePassXC Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 or (at your option) + * version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef KEEPASSXC_PASSGEN_H +#define KEEPASSXC_PASSGEN_H + +#include "Command.h" + +class PassGen : public Command +{ +public: + PassGen(); + ~PassGen(); + int execute(QStringList arguments); +}; + +#endif // KEEPASSXC_PASSGEN_H diff --git a/src/cli/keepassxc-cli.1 b/src/cli/keepassxc-cli.1 index a9145b27e..6a772e7cd 100644 --- a/src/cli/keepassxc-cli.1 +++ b/src/cli/keepassxc-cli.1 @@ -1,4 +1,4 @@ -.TH KEEPASSXC-CLI 1 "Aug 22, 2017" +.TH KEEPASSXC-CLI 1 "Jan 19, 2018" .SH NAME keepassxc-cli \- command line interface for the \fBKeePassXC\fP password manager. @@ -19,6 +19,9 @@ Adds a new entry to a database. A password can be generated (\fI-g\fP option), o .IP "clip [options] [timeout]" Copies the password of a database entry to the clipboard. If multiple entries with the same name exist in different groups, only the password for the first one is going to be copied. For copying the password of an entry in a specific group, the group path to the entry should be specified as well, instead of just the name. Optionally, a timeout in seconds can be specified to automatically clear the clipboard. +.IP "diceware [options] " +Generate a random diceware passphrase. + .IP "edit [options] " Edits a database entry. A password can be generated (\fI-g\fP option), or a prompt can be displayed to input the password (\fI-p\fP option). @@ -37,6 +40,9 @@ Lists the contents of a group in a database. If no group is specified, it will d .IP "merge [options] " Merges two databases together. The first database file is going to be replaced by the result of the merge, for that reason it is advisable to keep a backup of the two database files before attempting a merge. In the case that both databases make use of the same credentials, the \fI--same-credentials\fP or \fI-s\fP option can be used. +.IP "passgen [options] " +Generate a random password + .IP "rm [options] " Removes an entry from a database. If the database has a recycle bin, the entry will be moved there. If the entry is already in the recycle bin, it will be removed permanently. @@ -104,6 +110,33 @@ with each attribute shown one-per-line in the given order. If no attributes are specified, a summary of the default attributes is given. +.SS "Diceware options" + +.IP "-w, --wordlist " +Path of the wordlist for the diceware generator. The wordlist must have > 1000 words, +otherwise the program will fail. If the wordlist has < 4000 words a warning will +be printed to STDERR. + + +.SS "PassGen options" + +.IP "-l" +Use lowercase characters for the password generator + +.IP "-u" +Use uppercase characters for the password generator + +.IP "-n" +Use numbers characters for the password generator + +.IP "-s" +Use special characters for the password generator + +.IP "-e" +Use extended ascii characters for the password generator + + + .SH REPORTING BUGS Bugs and feature requests can be reported on GitHub at https://github.com/keepassxreboot/keepassxc/issues.