• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IJHack / QtPass / 24080647377

07 Apr 2026 12:11PM UTC coverage: 20.05%. First build
24080647377

Pull #895

github

web-flow
Merge 6219e3bd7 into e7f408717
Pull Request #895: fix: kill stale GPG agents before key generation

17 of 37 new or added lines in 3 files covered. (45.95%)

1047 of 5222 relevant lines covered (20.05%)

7.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

33.33
/src/pass.h
1
// SPDX-FileCopyrightText: 2016 Anne Jan Brouwer
2
// SPDX-License-Identifier: GPL-3.0-or-later
3
#ifndef SRC_PASS_H_
4
#define SRC_PASS_H_
5

6
#include "enums.h"
7
#include "executor.h"
8
#include "userinfo.h"
9

10
#include <QProcess>
11
#include <QQueue>
12
#include <QString>
13
#include <QStringList>
14
#include <cassert>
15
#include <map>
16

NEW
17
struct ResolvedGpgconfCommand {
×
18
  QString program;
19
  QStringList arguments;
20
};
21

22
/**
23
 * @class Pass
24
 * @brief Abstract base class for password store operations.
25
 *
26
 * Pass provides an abstraction layer for password management, supporting both
27
 * the native 'pass' utility and gopass/imitation backends. It handles:
28
 * - Password file operations (show, insert, remove, move, copy)
29
 * - GPG key management and Git integration
30
 * - OTP generation
31
 * - Random password generation
32
 *
33
 * Subclasses must implement Git and password operations.
34
 */
35
class Pass : public QObject {
36
  Q_OBJECT
×
37

38
  bool wrapperRunning;
39
  QStringList env;
40

41
protected:
42
  Executor exec;
43

44
  using PROCESS = Enums::PROCESS;
45

46
public:
47
  /**
48
   * @brief Construct a Pass instance.
49
   */
50
  Pass();
51
  /**
52
   * @brief Initialize the Pass instance.
53
   */
54
  void init();
55
  /**
56
   * @brief Check if GPG supports Ed25519 encryption.
57
   * @return true if Ed25519 is supported.
58
   */
59
  static bool gpgSupportsEd25519();
60
  /**
61
   * @brief Get default key template for new GPG keys.
62
   * @return Default template string.
63
   */
64
  static QString getDefaultKeyTemplate();
65

66
  ~Pass() override = default;
6✔
67

68
  // Git operations
69
  /**
70
   * @brief Initialize Git repository in password store.
71
   */
72
  virtual void GitInit() = 0;
73
  /**
74
   * @brief Pull changes from remote Git repository.
75
   */
76
  virtual void GitPull() = 0;
77
  /**
78
   * @brief Pull with rebase from remote.
79
   */
80
  virtual void GitPull_b() = 0;
81
  /**
82
   * @brief Push changes to remote Git repository.
83
   */
84
  virtual void GitPush() = 0;
85

86
  // Password operations
87
  /**
88
   * @brief Show decrypted password file.
89
   * @param file Path to password file relative to store root.
90
   */
91
  virtual void Show(QString file) = 0;
92
  /**
93
   * @brief Generate OTP for password file.
94
   * @param file Path to password file.
95
   */
96
  virtual void OtpGenerate(QString file) = 0;
97
  /**
98
   * @brief Insert or update password.
99
   * @param file Path to password file.
100
   * @param value Password content to store.
101
   * @param force Overwrite existing file.
102
   */
103
  virtual void Insert(QString file, QString value, bool force) = 0;
104
  /**
105
   * @brief Remove password file or directory.
106
   * @param file Path to remove.
107
   * @param isDir true if removing a directory.
108
   */
109
  virtual void Remove(QString file, bool isDir) = 0;
110
  /**
111
   * @brief Move password file or directory.
112
   * @param srcDir Source path.
113
   * @param dest Destination path.
114
   * @param force Overwrite existing.
115
   */
116
  virtual void Move(const QString srcDir, const QString dest,
117
                    const bool force = false) = 0;
118
  /**
119
   * @brief Copy password file or directory.
120
   * @param srcDir Source path.
121
   * @param dest Destination path.
122
   * @param force Overwrite existing.
123
   */
124
  virtual void Copy(const QString srcDir, const QString dest,
125
                    const bool force = false) = 0;
126
  /**
127
   * @brief Initialize new password store.
128
   * @param path Root of password store.
129
   * @param users List of recipient GPG keys.
130
   */
131
  virtual void Init(QString path, const QList<UserInfo> &users) = 0;
132
  /**
133
   * @brief Generate random password.
134
   * @param length Password length.
135
   * @param charset Character set to use.
136
   * @return Generated password.
137
   */
138
  virtual auto generatePassword(unsigned int length, const QString &charset)
139
      -> QString;
140

141
  // GPG operations
142
  /**
143
   * @brief Generate GPG keys using batch script.
144
   * @param batch GPG batch script content.
145
   */
146
  void GenerateGPGKeys(QString batch);
147
  /**
148
   * @brief List GPG keys matching patterns.
149
   * @param keystrings List of search patterns.
150
   * @param secret Include secret keys.
151
   * @return List of matching keys.
152
   */
153
  auto listKeys(QStringList keystrings, bool secret = false) -> QList<UserInfo>;
154
  /**
155
   * @brief List GPG keys.
156
   * @param keystring Search pattern.
157
   * @param secret Include secret keys.
158
   * @return List of matching keys.
159
   */
160
  auto listKeys(const QString &keystring = "", bool secret = false)
161
      -> QList<UserInfo>;
162
  /**
163
   * @brief Update environment for subprocesses.
164
   */
165
  void updateEnv();
166

167
  // Static helpers
168
  /**
169
   * @brief Resolve the gpgconf command to kill agents.
170
   * @param gpgPath Path to gpg executable.
171
   * @return Resolved command with program and arguments.
172
   */
173
  static ResolvedGpgconfCommand resolveGpgconfCommand(const QString &gpgPath);
174
  /**
175
   * @brief Get .gpg-id file path for a password file.
176
   * @param for_file Path to password file.
177
   * @return Path to .gpg-id file.
178
   */
179
  static auto getGpgIdPath(const QString &for_file) -> QString;
180
  /**
181
   * @brief Get list of recipients for a password file.
182
   * @param for_file Path to password file.
183
   * @return List of recipient key IDs.
184
   */
185
  static auto getRecipientList(const QString &for_file) -> QStringList;
186
  /**
187
   * @brief Get recipients as string.
188
   * @param for_file Path to password file.
189
   * @param separator Separator between recipients.
190
   * @param count Pointer to store recipient count.
191
   * @return List of recipient key IDs.
192
   */
193
  static auto getRecipientString(const QString &for_file,
194
                                 const QString &separator = " ",
195
                                 int *count = nullptr) -> QStringList;
196

197
protected:
198
  /**
199
   * @brief Execute external wrapper command.
200
   * @param id Process identifier.
201
   * @param app Executable path.
202
   * @param args Command arguments.
203
   * @param readStdout Capture stdout.
204
   * @param readStderr Capture stderr.
205
   */
206
  void executeWrapper(PROCESS id, const QString &app, const QStringList &args,
207
                      bool readStdout = true, bool readStderr = true);
208
  /**
209
   * @brief Generate random password from charset.
210
   * @param charset Character set.
211
   * @param length Password length.
212
   * @return Generated password.
213
   */
214
  auto generateRandomPassword(const QString &charset, unsigned int length)
215
      -> QString;
216
  /**
217
   * @brief Generate random number in range.
218
   * @param bound Upper bound (exclusive).
219
   * @return Random number.
220
   */
221
  auto boundedRandom(quint32 bound) -> quint32;
222

223
  /**
224
   * @brief Execute wrapper with input.
225
   * @param id Process identifier.
226
   * @param app Executable path.
227
   * @param args Command arguments.
228
   * @param input Input to pass to stdin.
229
   * @param readStdout Capture stdout.
230
   * @param readStderr Capture stderr.
231
   */
232
  virtual void executeWrapper(PROCESS id, const QString &app,
233
                              const QStringList &args, QString input,
234
                              bool readStdout = true, bool readStderr = true);
235

236
protected slots:
237
  /**
238
   * @brief Handle process completion.
239
   * @param id Process identifier.
240
   * @param exitCode Process exit code.
241
   * @param out Standard output.
242
   * @param err Standard error.
243
   */
244
  virtual void finished(int id, int exitCode, const QString &out,
245
                        const QString &err);
246

247
signals:
248
  /**
249
   * @brief Emitted when a process error occurs.
250
   */
251
  void error(QProcess::ProcessError);
252
  /**
253
   * @brief Emitted before executing a command.
254
   */
255
  void startingExecuteWrapper();
256
  /**
257
   * @brief Emit status message.
258
   * @param Message text.
259
   * @param Timeout in ms.
260
   */
261
  void statusMsg(const QString &, int);
262
  /**
263
   * @brief Emit critical error.
264
   * @param title Error title.
265
   * @param message Error message.
266
   */
267
  void critical(const QString &, const QString &);
268

269
  /**
270
   * @brief Emitted on process error exit.
271
   */
272
  void processErrorExit(int exitCode, const QString &err);
273

274
  /**
275
   * @brief Emitted when any operation finishes.
276
   */
277
  void finishedAny(const QString &, const QString &);
278
  /**
279
   * @brief Emitted when Git init finishes.
280
   */
281
  void finishedGitInit(const QString &, const QString &);
282
  /**
283
   * @brief Emitted when Git pull finishes.
284
   */
285
  void finishedGitPull(const QString &, const QString &);
286
  /**
287
   * @brief Emitted when Git push finishes.
288
   */
289
  void finishedGitPush(const QString &, const QString &);
290
  /**
291
   * @brief Emitted when show finishes.
292
   */
293
  void finishedShow(const QString &);
294
  /**
295
   * @brief Emitted when OTP generation finishes.
296
   */
297
  void finishedOtpGenerate(const QString &);
298
  /**
299
   * @brief Emitted when insert finishes.
300
   */
301
  void finishedInsert(const QString &, const QString &);
302
  /**
303
   * @brief Emitted when remove finishes.
304
   */
305
  void finishedRemove(const QString &, const QString &);
306
  /**
307
   * @brief Emitted when init finishes.
308
   */
309
  void finishedInit(const QString &, const QString &);
310
  /**
311
   * @brief Emitted when move finishes.
312
   */
313
  void finishedMove(const QString &, const QString &);
314
  /**
315
   * @brief Emitted when copy finishes.
316
   */
317
  void finishedCopy(const QString &, const QString &);
318
  /**
319
   * @brief Emitted when generate finishes.
320
   */
321
  void finishedGenerate(const QString &, const QString &);
322
  /**
323
   * @brief Emitted when GPG key generation finishes.
324
   */
325
  void finishedGenerateGPGKeys(const QString &, const QString &);
326
};
327

328
#endif // SRC_PASS_H_
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc