1 /*
2 * Copyright (C) 2018 Rafael Ostertag
3 *
4 * This file is part of YAPET.
5 *
6 * YAPET is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
9 * version.
10 *
11 * YAPET is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * YAPET. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Additional permission under GNU GPL version 3 section 7
20 *
21 * If you modify this program, or any covered work, by linking or combining it
22 * with the OpenSSL project's OpenSSL library (or a modified version of that
23 * library), containing parts covered by the terms of the OpenSSL or SSLeay
24 * licenses, Rafael Ostertag grants you additional permission to convey the
25 * resulting work. Corresponding Source for a non-source form of such a
26 * combination shall include the source code for the parts of OpenSSL used as
27 * well as that of the covered work.
28 */
29
30 #include <cassert>
31 #include <memory>
32 #include <typeinfo>
33
34 #include "aes256factory.hh"
35 #include "consts.h"
36 #include "createfile.h"
37 #include "globals.h"
38 #include "intl.h"
39 #include "utils.hh"
40
41 //
42 // Private
43 //
44
window_close_handler(YACURS::Event & e)45 void CreateFile::window_close_handler(YACURS::Event& e) {
46 assert(e == YACURS::EVT_WINDOW_CLOSE);
47
48 YACURS::EventEx<YACURS::WindowBase*>& evt =
49 dynamic_cast<YACURS::EventEx<YACURS::WindowBase*>&>(e);
50
51 if (evt.data() == filesavedialog) {
52 if (filesavedialog->dialog_state() == YACURS::DIALOG_OK) {
53 _filepath = filesavedialog->filepath();
54 assert(promptpassword == nullptr);
55 promptpassword = new NewPasswordDialog(_filepath);
56 promptpassword->show();
57 } else {
58 YACURS::EventQueue::submit(
59 YACURS::EventEx<CreateFile*>(YAPET::EVT_APOPTOSIS, this));
60 }
61
62 yapet::deleteAndZero(&filesavedialog);
63
64 return;
65 }
66
67 if (evt.data() == promptpassword) {
68 if (promptpassword->dialog_state() == YACURS::DIALOG_OK) {
69 assert(promptpassword->match());
70 assert(!_filepath.empty());
71
72 // Set file into configuration, so that it receives .pet
73 // suffix
74 YAPET::Globals::config.petfile.set(_filepath);
75
76 try {
77 auto password{yapet::toSecureArray(promptpassword->password())};
78 auto keyingParameters{yapet::Key256::newDefaultKeyingParameters()};
79 std::shared_ptr<yapet::AbstractCryptoFactory> cryptoFactory{
80 new yapet::Aes256Factory{password, keyingParameters}};
81 mainwindow.load_password_file(YAPET::Globals::config.petfile,
82 cryptoFactory, true);
83
84 YACURS::EventQueue::submit(
85 YACURS::EventEx<CreateFile*>(YAPET::EVT_APOPTOSIS, this));
86 } catch (std::exception& ex) {
87 assert(generror == nullptr);
88 generror = new YACURS::MessageBox2(_("Error"),
89 _("Got following error"),
90 ex.what(), YACURS::OK_ONLY);
91 generror->show();
92 }
93
94 } else {
95 YACURS::EventQueue::submit(
96 YACURS::EventEx<CreateFile*>(YAPET::EVT_APOPTOSIS, this));
97 }
98
99 // Do not put aptoptosis here, since here we can't decide
100 // whether we had an exception or not. And if we had an
101 // exception, generror is active and we have to wait for the
102 // user to close it. If we have an exception, generror handler
103 // takes care
104
105 yapet::deleteAndZero(&promptpassword);
106 return;
107 }
108
109 if (evt.data() == confirmsave) {
110 switch (confirmsave->dialog_state()) {
111 case YACURS::DIALOG_YES:
112 if (mainwindow.save_records())
113 run();
114 else
115 YACURS::EventQueue::submit(YACURS::EventEx<CreateFile*>(
116 YAPET::EVT_APOPTOSIS, this));
117 break;
118 case YACURS::DIALOG_NO:
119 ignore_unsaved_file = true;
120 run();
121 break;
122 case YACURS::DIALOG_CANCEL:
123 YACURS::EventQueue::submit(
124 YACURS::EventEx<CreateFile*>(YAPET::EVT_APOPTOSIS, this));
125 break;
126 default:
127 throw std::runtime_error{
128 _("Unexpected dialog state for confirmsave dialog")};
129 break;
130 }
131
132 yapet::deleteAndZero(&confirmsave);
133 return;
134 }
135
136 if (evt.data() == generror) {
137 yapet::deleteAndZero(&generror);
138 YACURS::EventQueue::submit(
139 YACURS::EventEx<CreateFile*>(YAPET::EVT_APOPTOSIS, this));
140 }
141 }
142
143 //
144 // Public
145 //
146
CreateFile(MainWindow & mw)147 CreateFile::CreateFile(MainWindow& mw)
148 : mainwindow{mw},
149 promptpassword{nullptr},
150 filesavedialog{nullptr},
151 confirmsave{nullptr},
152 generror{nullptr},
153 _currentLoadedFile{mw.currentFilename()},
154 _filepath{},
155 ignore_unsaved_file{false} {
156 YACURS::EventQueue::connect_event(YACURS::EventConnectorMethod1<CreateFile>(
157 YACURS::EVT_WINDOW_CLOSE, this, &CreateFile::window_close_handler));
158 }
159
~CreateFile()160 CreateFile::~CreateFile() {
161 if (promptpassword) delete promptpassword;
162 if (filesavedialog) delete filesavedialog;
163 if (confirmsave) delete confirmsave;
164 if (generror) delete generror;
165
166 YACURS::EventQueue::disconnect_event(
167 YACURS::EventConnectorMethod1<CreateFile>(
168 YACURS::EVT_WINDOW_CLOSE, this, &CreateFile::window_close_handler));
169 }
170
run()171 void CreateFile::run() {
172 if (!ignore_unsaved_file && YAPET::Globals::records_changed) {
173 assert(confirmsave == nullptr);
174 confirmsave = new YACURS::MessageBox2(
175 _("Unsaved Changes"), _currentLoadedFile,
176 _("has unsaved changes. Do you want to save?"),
177 YACURS::YESNOCANCEL);
178 confirmsave->show();
179 } else {
180 assert(filesavedialog == nullptr);
181 // FileSaveDialog uses chdir().
182 filesavedialog = new YACURS::FileSaveDialog(std::string(), true);
183 filesavedialog->suffix(YAPET::Consts::DEFAULT_FILE_SUFFIX);
184 filesavedialog->show();
185 }
186 }
187