8#include <QRandomGenerator>
9#include <QRegularExpression>
31Pass::Pass() : wrapperRunning(false), env(QProcess::systemEnvironment()) {
33 static_cast<void (
Executor::*)(
int,
int,
const QString &,
34 const QString &)
>(&Executor::finished),
42 env.append(
"WSLENV=PASSWORD_STORE_DIR/p");
46 const QStringList &args,
bool readStdout,
52 const QStringList &args, QString input,
53 bool readStdout,
bool readStderr) {
58 readStdout, readStderr);
64 if (QFile(
"/usr/local/MacGPG2/bin").exists())
65 env.replaceInStrings(
"PATH=",
"PATH=/usr/local/MacGPG2/bin:");
67 if (env.filter(
"/usr/local/bin").isEmpty())
68 env.replaceInStrings(
"PATH=",
"PATH=/usr/local/bin:");
73 absHome.makeAbsolute();
74 env <<
"GNUPGHOME=" + absHome.path();
92 args.append(
"--secure");
99 args.append(
"--symbols");
101 args.append(QString::number(length));
105 static const QRegularExpression literalNewLines{
"[\\n\\r]"};
106 passwd.remove(literalNewLines);
110 qDebug() << __FILE__ <<
":" << __LINE__ <<
"\t"
116 if (charset.length() > 0) {
117 passwd = generateRandomPassword(charset, length);
120 tr(
"No characters chosen"),
121 tr(
"Can't generate password, there are no characters to choose from "
122 "set in the configuration!"));
134 {
"--gen-key",
"--no-tty",
"--batch"}, std::move(batch));
148 QList<UserInfo> users;
149 QStringList args = {
"--no-tty",
"--with-colons",
"--with-fingerprint"};
150 args.append(secret ?
"--list-secret-keys" :
"--list-keys");
152 for (
const QString &keystring :
AS_CONST(keystrings)) {
153 if (!keystring.isEmpty()) {
154 args.append(keystring);
162#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
163 const QStringList keys =
166 const QStringList keys =
170 for (
const QString &key : keys) {
171 QStringList props = key.split(
':');
172 if (props.size() < 10) {
175 if (props[0] == (secret ?
"sec" :
"pub")) {
176 if (!current_user.
key_id.isEmpty()) {
177 users.append(current_user);
180 current_user.
key_id = props[4];
181 current_user.
name = props[9].toUtf8();
182 current_user.
validity = props[1][0].toLatin1();
183 current_user.
created.setSecsSinceEpoch(props[5].toUInt());
184 current_user.
expiry.setSecsSinceEpoch(props[6].toUInt());
185 }
else if (current_user.
name.isEmpty() && props[0] ==
"uid") {
186 current_user.
name = props[9];
187 }
else if ((props[0] ==
"fpr") && props[9].endsWith(current_user.
key_id)) {
188 current_user.
key_id = props[9];
191 if (!current_user.
key_id.isEmpty()) {
192 users.append(current_user);
204 return listKeys(QStringList(keystring), secret);
218 const QString &err) {
219 auto pid =
static_cast<PROCESS>(id);
237 case PASS_OTP_GENERATE:
260 dbg() <<
"Unhandled process type" << pid;
272 QStringList envSigningKey = env.filter(
"PASSWORD_STORE_SIGNING_KEY=");
274 if (envSigningKey.isEmpty()) {
275 if (!currentSigningKey.isEmpty()) {
278 env.append(
"PASSWORD_STORE_SIGNING_KEY=" + currentSigningKey);
281 if (currentSigningKey.isEmpty()) {
284 env.removeAll(envSigningKey.first());
288 env.replaceInStrings(envSigningKey.first(),
289 "PASSWORD_STORE_SIGNING_KEY=" + currentSigningKey);
293 QStringList store = env.filter(
"PASSWORD_STORE_DIR=");
294 if (store.isEmpty()) {
301 env.replaceInStrings(store.first(),
"PASSWORD_STORE_DIR=" +
315 QString normalizedFile = QDir::fromNativeSeparators(for_file);
316 QString fullPath = normalizedFile.startsWith(passStore)
318 : passStore +
"/" + normalizedFile;
319 QDir gpgIdDir(QFileInfo(fullPath).absoluteDir());
321 while (gpgIdDir.exists() && gpgIdDir.absolutePath().startsWith(passStore)) {
322 if (QFile(gpgIdDir.absoluteFilePath(
".gpg-id")).exists()) {
326 if (!gpgIdDir.cdUp()) {
330 QString gpgIdPath(found ? gpgIdDir.absoluteFilePath(
".gpg-id")
342 QFile gpgId(getGpgIdPath(for_file));
343 if (!gpgId.open(QIODevice::ReadOnly | QIODevice::Text)) {
346 QStringList recipients;
347 while (!gpgId.atEnd()) {
348 QString recipient(gpgId.readLine());
349 recipient = recipient.split(
"#")[0].trimmed();
350 if (!recipient.isEmpty()) {
351 recipients += recipient;
365 int *count) -> QStringList {
380 const quint32 max_mod_bound = (1 + ~bound) % bound;
383 randval = QRandomGenerator::system()->generate();
384 }
while (randval < max_mod_bound);
386 return randval % bound;
392 for (
unsigned int i = 0; i < length; ++i) {
393 out.append(charset.at(
static_cast<int>(
394 boundedRandom(
static_cast<quint32
>(charset.length())))));
Executes external commands for handleing password, git and other data.
static auto executeBlocking(QString app, const QStringList &args, const QString &input=QString(), QString *process_out=nullptr, QString *process_err=nullptr) -> int
Executor::executeBlocking blocking version of the executor, takes input and presents it as stdin.
void execute(int id, const QString &app, const QStringList &args, bool readStdout, bool readStderr=true)
Executor::execute execute an app.
void setEnvironment(const QStringList &env)
Executor::setEnvironment set environment variables for executor processes.
void starting()
starting signal that is emited when process starts
void startingExecuteWrapper()
void GenerateGPGKeys(QString batch)
Pass::GenerateGPGKeys internal gpg keypair generator . .
void finishedCopy(const QString &, const QString &)
void finishedShow(const QString &)
void finishedRemove(const QString &, const QString &)
void finishedMove(const QString &, const QString &)
auto boundedRandom(quint32 bound) -> quint32
void finishedGitInit(const QString &, const QString &)
Pass()
Pass::Pass wrapper for using either pass or the pass imitation.
static auto getRecipientString(const QString &for_file, const QString &separator=" ", int *count=NULL) -> QStringList
Pass::getRecipientString formated string for use with GPG.
void executeWrapper(PROCESS id, const QString &app, const QStringList &args, bool readStdout=true, bool readStderr=true)
static auto getRecipientList(const QString &for_file) -> QStringList
Pass::getRecipientList return list of gpg-id's to encrypt for.
auto listKeys(QStringList keystrings, bool secret=false) -> QList< UserInfo >
Pass::listKeys list users.
void finishedInsert(const QString &, const QString &)
void finishedInit(const QString &, const QString &)
static auto getGpgIdPath(const QString &for_file) -> QString
Pass::getGpgIdPath return gpgid file path for some file (folder).
void finishedOtpGenerate(const QString &)
virtual auto Generate_b(unsigned int length, const QString &charset) -> QString
Pass::Generate use either pwgen or internal password generator.
void processErrorExit(int exitCode, const QString &err)
void finishedGitPull(const QString &, const QString &)
void finishedGitPush(const QString &, const QString &)
void updateEnv()
Pass::updateEnv update the execution environment (used when switching profiles)
virtual void finished(int id, int exitCode, const QString &out, const QString &err)
Pass::processFinished reemits specific signal based on what process has finished.
void finishedGenerateGPGKeys(const QString &, const QString &)
auto generateRandomPassword(const QString &charset, unsigned int length) -> QString
static auto getPwgenExecutable(const QString &defaultValue=QVariant().toString()) -> QString
static auto getGpgHome(const QString &defaultValue=QVariant().toString()) -> QString
static auto getPassStore(const QString &defaultValue=QVariant().toString()) -> QString
static auto isAvoidCapitals(const bool &defaultValue=QVariant().toBool()) -> bool
static auto getGpgExecutable(const QString &defaultValue=QVariant().toString()) -> QString
static auto getPassSigningKey(const QString &defaultValue=QVariant().toString()) -> QString
static auto isUseSymbols(const bool &defaultValue=QVariant().toBool()) -> bool
static auto isLessRandom(const bool &defaultValue=QVariant().toBool()) -> bool
static auto isUsePwgen(const bool &defaultValue=QVariant().toBool()) -> bool
static auto isAvoidNumbers(const bool &defaultValue=QVariant().toBool()) -> bool
static auto newLinesRegex() -> const QRegularExpression &
Stores key info lines including validity, creation date and more.
QString key_id
UserInfo::key_id hexadecimal representation.
QDateTime created
UserInfo::created date/time key was created.
QString name
UserInfo::name full name.
char validity
UserInfo::validity GnuPG representation of validity http://git.gnupg.org/cgi-bin/gitweb....
QDateTime expiry
UserInfo::expiry date/time key expires.