1 /*
2  * Author: Copyright (C) Andrzej Surowiec 2012
3  *                      Parts Rudolf Boeddeker  Date: 2013-08-13
4  * Copyright (c) 2012-2018 Nitrokey UG
5  *
6  * This file is part of Nitrokey App.
7  *
8  * Nitrokey App is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * any later version.
12  *
13  * Nitrokey App is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Nitrokey App. If not, see <http://www.gnu.org/licenses/>.
20  *
21  * SPDX-License-Identifier: GPL-3.0
22  */
23 
24 #ifndef MAINWINDOW_H
25 #define MAINWINDOW_H
26 
27 
28 #include <QMainWindow>
29 #include <QValidator>
30 #include <QMutex>
31 #include <climits>
32 #include <src/GUI/StorageActions.h>
33 #include "hotpslot.h"
34 #include "GUI/Tray.h"
35 #include "GUI/Clipboard.h"
36 #include "GUI/Authentication.h"
37 #include "stick20responsedialog.h"
38 #include "stick20debugdialog.h"
39 #include <atomic>
40 
41 
42 namespace Ui {
43 class MainWindow;
44 }
45 
46 class Tray;
47 
48 enum class ConnectionState{
49   disconnected, connected, long_operation
50 };
51 
52 class MainWindow : public QMainWindow {
53   Q_OBJECT
54 
55 public :
56     explicit MainWindow(QWidget *parent = 0);
57   ~MainWindow();
58 
59 protected:
60   void closeEvent(QCloseEvent *event) override;
61   void showEvent(QShowEvent *event) override;
62 
63 private:
64   Q_DISABLE_COPY(MainWindow);
65 
66   Ui::MainWindow *ui;
67   Clipboard clipboard;
68   Authentication auth_admin;
69   Authentication auth_user;
70   StorageActions storage;
71   Tray tray;
72   const unsigned char HOTP_SlotCount;
73   const unsigned char TOTP_SlotCount;
74   DebugDialog *debug;
75 
76   void keyPressEvent(QKeyEvent *keyevent) override;
77 
78   bool validate_raw_secret(const char *secret) const;
79   void initialTimeReset();
80   QMutex check_connection_mutex;
81   QString nkpro_user_PIN;
82   void startDebug();
83   QTimer *keepDeviceOnlineTimer;
84 
85 
86   bool PWS_Access = false;
87   const int PWS_CreatePWSize = 20;
88 
89   bool set_initial_time;
90 
91 
92   QString DebugText;
93 
94   int ExecStickCmd(const char *Cmdline_);
95   std::string getNextCode(uint8_t slotNumber);
96 
97   void generateHOTPConfig(OTPSlot *slot);
98   void generateTOTPConfig(OTPSlot *slot);
99   void generateAllConfigs();
100 
101 //  void refreshStick20StatusData();
102   void translateDeviceStatusToUserMessage(const int getStatus);
103 
104 public slots:
105   void startAboutDialog();
106   void startHelpAction();
107   void startConfiguration(bool changeTab = true);
108   void startConfigurationMain();
109   void PWS_Clicked_EnablePWSAccess();
110 
111   int factoryResetAction();
112   void getTOTPDialog(int slot);
113   void getHOTPDialog(int slot);
114   void PWS_ExceClickedSlot(int Slot);
115   void startStick20ActionChangeUserPIN();
116   void startStick20ActionChangeAdminPIN();
117   void startStick20ActionChangeUpdatePIN();
118   void startResetUserPassword();
119   void startLockDeviceAction(bool ask_for_confirmation = true);
120   void updateProgressBar(int i);
121   void show_progress_window();
122 
123 signals:
124   void DeviceConnected();
125   void DeviceDisconnected();
126   void PWS_unlocked();
127   void PWS_slot_saved(int slot_no);
128   void DeviceLocked();
129   void FactoryReset();
130   void PWS_progress(int p);
131   void OperationInProgress(int p);
132   void ShortOperationBegins(QString msg);
133   void ShortOperationEnds();
134   void OTP_slot_write(int slot_no, bool isHOTP);
135   void DebugData(QString msg);
136   void LongOperationStart();
137 
138 private slots:
139   void manageStartPage();
140   void on_longOperationStart();
141   void on_KeepDeviceOnline();
142   void on_DeviceConnected();
143   void on_DeviceDisconnected();
144   void generateComboBoxEntrys();
145   void on_enableUserPasswordCheckBox_clicked(bool checked);
146 
147   void resizeMin();
148   void ready();
149   void checkConnection();
150   void storage_check_symlink();
151 
152   void on_writeButton_clicked();
153   void displayCurrentTotpSlotConfig(uint8_t slotNo);
154   void displayCurrentHotpSlotConfig(uint8_t slotNo);
155   void displayCurrentSlotConfig();
156   void displayCurrentGeneralConfig();
157   void on_slotComboBox_currentIndexChanged(int index);
158   void on_hexRadioButton_toggled(bool checked);
159   void on_base32RadioButton_toggled(bool checked);
160   void on_setToZeroButton_clicked();
161   void on_setToRandomButton_clicked();
162   void on_enableUserPasswordCheckBox_toggled(bool checked);
163   void on_writeGeneralConfigButton_clicked();
164 
165   void checkTextEdited();
166 
167   // Functions for password safe
168   void SetupPasswordSafeConfig(void);
169 
170   void on_eraseButton_clicked();
171   void on_randomSecretButton_clicked();
172   void on_checkBox_toggled(bool checked);
173 
174   void startStickDebug();
175   void load_settings_page();
176 
177   void on_PWS_ButtonClearSlot_clicked();
178   void on_PWS_ComboBoxSelectSlot_currentIndexChanged(int index);
179   void on_PWS_CheckBoxHideSecret_toggled(bool checked);
180   void on_PWS_ButtonClose_pressed();
181   void on_PWS_ButtonCreatePW_clicked();
182   void on_PWS_ButtonSaveSlot_clicked();
183   void on_PWS_ButtonEnable_clicked();
184   void on_counterEdit_editingFinished();
185   void on_radioButton_2_toggled(bool checked);
186   void on_radioButton_toggled(bool checked);
187   void on_PWS_EditSlotName_textChanged(const QString &arg1);
188   void on_PWS_EditLoginName_textChanged(const QString &arg1);
189   void on_PWS_EditPassword_textChanged(const QString &arg1);
190 
191 
192   void on_btn_writeSettings_clicked();
193 
194   void on_btn_select_debug_file_path_clicked();
195 
196   void on_PWS_Lock_clicked();
197 
198   void on_btn_copyToClipboard_clicked();
199 
200   void on_btn_select_debug_console_clicked();
201 
202 public:
203   void generateOTPConfig(OTPSlot *slot);
204   unsigned int get_supported_secret_length_base32() const;
205   unsigned int get_supported_secret_length_hex() const;
206 
207   std::atomic_bool long_operation_in_progress {false};
208   std::shared_ptr<Stick20ResponseDialog> progress_window;
209 
210   void PWS_set_controls_enabled(bool enabled) const;
211 
212   ConnectionState connectionState = ConnectionState::disconnected;
213 
214   void set_commands_delay(int delay_in_ms);
215 
216   void first_run();
217   void enable_admin_commands();
218   void set_debug_file(QString log_file_name);
219   void set_debug_window();
220 
221   void set_debug_mode();
222   void set_debug_level(int debug_level);
223 
224   void hideOnStartup();
225 
226 private:
227   bool debug_mode = false;
228   bool suppress_next_show = false;
229 
230   void showNotificationLabel();
231 
232   unsigned int roundToNextMultiple(const int number, const int multipleOf) const;
233 
234   QString getOTPSecretCleaned(QString secret_input);
235 
236   void make_UI_enabled(bool enabled);
237 };
238 
239 class utf8FieldLengthValidator : public QValidator {
240   Q_OBJECT
241 private:
242   int field_max_length;
243   Q_DISABLE_COPY(utf8FieldLengthValidator);
244 
245 
246 public:
247   explicit utf8FieldLengthValidator(QObject *parent = 0);
248   explicit utf8FieldLengthValidator(int _field_max_length, QObject *parent = 0)
QValidator(parent)249       : QValidator(parent), field_max_length(_field_max_length) {}
validate(QString & input,int &)250   virtual State validate(QString &input, int &) const {
251 
252     int chars_left = field_max_length - input.toUtf8().size();
253 
254     if (chars_left >= 0) {
255       return Acceptable;
256     }
257     return Invalid;
258   }
259 };
260 
261 #endif // MAINWINDOW_H
262