-rw-r--r-- | library/password.cpp | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/library/password.cpp b/library/password.cpp new file mode 100644 index 0000000..3be6efe --- a/dev/null +++ b/library/password.cpp | |||
@@ -0,0 +1,323 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | #include "password.h" | ||
21 | #include "config.h" | ||
22 | #include "global.h" | ||
23 | #include "backend/contact.h" | ||
24 | #include <qlabel.h> | ||
25 | #include <qlineedit.h> | ||
26 | #include <qtextview.h> | ||
27 | #include <qstring.h> | ||
28 | #include <qapplication.h> | ||
29 | #include <qfile.h> | ||
30 | #include <qwindowsystem_qws.h> | ||
31 | |||
32 | #include <qdialog.h> | ||
33 | |||
34 | #include <unistd.h> //for sleep | ||
35 | #include "passwordbase_p.h" | ||
36 | |||
37 | class PasswordDialog : public PasswordBase | ||
38 | { | ||
39 | Q_OBJECT | ||
40 | |||
41 | public: | ||
42 | PasswordDialog( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); | ||
43 | ~PasswordDialog(); | ||
44 | |||
45 | void clear(); | ||
46 | void setPrompt( const QString& ); | ||
47 | |||
48 | signals: | ||
49 | void passwordEntered( const QString& ); | ||
50 | |||
51 | protected: | ||
52 | bool eventFilter( QObject*, QEvent* ); | ||
53 | void keyPressEvent( QKeyEvent * ); | ||
54 | |||
55 | private: | ||
56 | void input( QString ); | ||
57 | friend class Password; | ||
58 | QString text; | ||
59 | }; | ||
60 | |||
61 | |||
62 | extern "C" char *crypt(const char *key, const char *salt); | ||
63 | static QString qcrypt(const QString& k, const char *salt) | ||
64 | { | ||
65 | return QString::fromUtf8(crypt(k.utf8(),salt)); | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * Constructs a PasswordDialog which is a child of 'parent', with the | ||
70 | * name 'name' and widget flags set to 'f' | ||
71 | */ | ||
72 | PasswordDialog::PasswordDialog( QWidget* parent, const char* name, WFlags fl ) | ||
73 | : PasswordBase( parent, name, fl ) | ||
74 | { | ||
75 | button_0->installEventFilter( this ); | ||
76 | button_1->installEventFilter( this ); | ||
77 | button_2->installEventFilter( this ); | ||
78 | button_3->installEventFilter( this ); | ||
79 | button_4->installEventFilter( this ); | ||
80 | button_5->installEventFilter( this ); | ||
81 | button_6->installEventFilter( this ); | ||
82 | button_7->installEventFilter( this ); | ||
83 | button_8->installEventFilter( this ); | ||
84 | button_9->installEventFilter( this ); | ||
85 | button_OK->installEventFilter( this ); | ||
86 | setFocus(); | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * Destroys the object and frees any allocated resources | ||
91 | */ | ||
92 | PasswordDialog::~PasswordDialog() | ||
93 | { | ||
94 | // no need to delete child widgets, Qt does it all for us | ||
95 | } | ||
96 | |||
97 | |||
98 | |||
99 | /*! | ||
100 | \reimp | ||
101 | */ | ||
102 | |||
103 | bool PasswordDialog::eventFilter( QObject*o, QEvent*e ) | ||
104 | { | ||
105 | if ( e->type() == QEvent::MouseButtonRelease ) { | ||
106 | if ( o == button_OK ) { | ||
107 | emit passwordEntered( text ); | ||
108 | } else { | ||
109 | QLabel *l = (QLabel*)o; | ||
110 | input(l->text()); | ||
111 | } | ||
112 | } | ||
113 | return FALSE; | ||
114 | } | ||
115 | |||
116 | |||
117 | /*! | ||
118 | \reimp | ||
119 | */ | ||
120 | |||
121 | void PasswordDialog::keyPressEvent( QKeyEvent * ) | ||
122 | { | ||
123 | #if 0 | ||
124 | if ( e->key() == Key_Enter || e->key() == Key_Return ) | ||
125 | emit passwordEntered( text ); | ||
126 | else | ||
127 | input( e->text() ); | ||
128 | #endif | ||
129 | } | ||
130 | |||
131 | |||
132 | /*! | ||
133 | |||
134 | */ | ||
135 | |||
136 | void PasswordDialog::input( QString c ) | ||
137 | { | ||
138 | text += c; | ||
139 | display->setText( text ); | ||
140 | } | ||
141 | |||
142 | /*! | ||
143 | |||
144 | */ | ||
145 | |||
146 | void PasswordDialog::setPrompt( const QString& s ) | ||
147 | { | ||
148 | prompt->setText( s ); | ||
149 | } | ||
150 | |||
151 | void PasswordDialog::clear() | ||
152 | { | ||
153 | text = ""; | ||
154 | input(""); | ||
155 | } | ||
156 | |||
157 | class PasswdDlg : public QDialog | ||
158 | { | ||
159 | public: | ||
160 | PasswdDlg( QWidget *parent, const char * name, bool modal, bool fullscreen = FALSE ) | ||
161 | : QDialog( parent, name, modal, fullscreen ? WStyle_NoBorder | WStyle_Customize | WStyle_StaysOnTop : 0 ), | ||
162 | modl(modal) | ||
163 | { | ||
164 | passw = new PasswordDialog( this ); | ||
165 | |||
166 | if ( fullscreen ) { | ||
167 | QRect desk = qApp->desktop()->geometry(); | ||
168 | setGeometry( 0, 0, desk.width(), desk.height() ); | ||
169 | } | ||
170 | |||
171 | connect( passw, SIGNAL(passwordEntered(const QString&)), | ||
172 | this, SLOT(accept()) ); | ||
173 | } | ||
174 | |||
175 | void resizeEvent( QResizeEvent * ) | ||
176 | { | ||
177 | passw->resize( size() ); | ||
178 | } | ||
179 | |||
180 | void reset() | ||
181 | { | ||
182 | passw->clear(); | ||
183 | } | ||
184 | |||
185 | void execNonModal() | ||
186 | { | ||
187 | if ( !modl ) { | ||
188 | reset(); | ||
189 | showFullScreen(); | ||
190 | do { | ||
191 | qApp->enter_loop(); | ||
192 | } while (result()!=1); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | void accept() | ||
197 | { | ||
198 | if ( !modl ) | ||
199 | qApp->exit_loop(); | ||
200 | QDialog::accept(); | ||
201 | } | ||
202 | |||
203 | PasswordDialog *passw; | ||
204 | bool modl; | ||
205 | }; | ||
206 | |||
207 | class OwnerDlg : public QDialog | ||
208 | { | ||
209 | public: | ||
210 | |||
211 | OwnerDlg( QWidget *parent, const char * name, Contact c, | ||
212 | bool modal, bool fullscreen = FALSE ) | ||
213 | : QDialog( parent, name, modal, | ||
214 | fullscreen ? | ||
215 | WStyle_NoBorder | WStyle_Customize | WStyle_StaysOnTop : 0 ) | ||
216 | { | ||
217 | if ( fullscreen ) { | ||
218 | QRect desk = qApp->desktop()->geometry(); | ||
219 | setGeometry( 0, 0, desk.width(), desk.height() ); | ||
220 | } | ||
221 | |||
222 | // set up contents. | ||
223 | QString text = "<H1>" + tr("Owner Information") + "</H1>"; | ||
224 | text += c.toRichText(); | ||
225 | tv = new QTextView(this); | ||
226 | tv->setText(text); | ||
227 | |||
228 | tv->viewport()->installEventFilter(this); | ||
229 | } | ||
230 | |||
231 | void resizeEvent( QResizeEvent * ) | ||
232 | { | ||
233 | tv->resize( size() ); | ||
234 | } | ||
235 | |||
236 | bool eventFilter(QObject *o, QEvent *e) | ||
237 | { | ||
238 | if (e->type() == QEvent::KeyPress || e->type() == QEvent::MouseButtonPress ) { | ||
239 | accept(); | ||
240 | return TRUE; | ||
241 | } | ||
242 | return QWidget::eventFilter(o, e); | ||
243 | } | ||
244 | |||
245 | void mousePressEvent( QMouseEvent * ) { accept(); } | ||
246 | |||
247 | private: | ||
248 | QTextView *tv; | ||
249 | }; | ||
250 | |||
251 | /*! | ||
252 | Returns a crypted password entered by the user when prompted with \a prompt | ||
253 | The returned value is QString::null if the user cancels the operation, | ||
254 | or the empty string if the user enters no password (but confirms the | ||
255 | dialog). | ||
256 | */ | ||
257 | |||
258 | QString Password::getPassword( const QString& prompt ) | ||
259 | { | ||
260 | PasswdDlg pd(0,0,TRUE); | ||
261 | pd.passw->setPrompt( prompt ); | ||
262 | |||
263 | pd.showMaximized(); | ||
264 | int r = pd.exec(); | ||
265 | |||
266 | if ( r == QDialog::Accepted ) { | ||
267 | if (pd.passw->text.isEmpty()) | ||
268 | return ""; | ||
269 | else | ||
270 | return qcrypt(pd.passw->text,"a0"); | ||
271 | } else { | ||
272 | return QString::null; | ||
273 | } | ||
274 | } | ||
275 | |||
276 | |||
277 | /*! | ||
278 | Prompt, fullscreen, for the user's passcode until they get it right. | ||
279 | |||
280 | If \a at_poweron is TRUE, the dialog is only used if the user's | ||
281 | preference request it at poweron; either way, the screen is always repainted | ||
282 | by this function. (this functionality may move to the caller of this function). | ||
283 | */ | ||
284 | |||
285 | void Password::authenticate(bool at_poweron) | ||
286 | { | ||
287 | Config cfg("Security"); | ||
288 | cfg.setGroup("Passcode"); | ||
289 | QString passcode = cfg.readEntry("passcode"); | ||
290 | if ( !passcode.isEmpty() | ||
291 | && (!at_poweron || cfg.readNumEntry("passcode_poweron",0)) ) | ||
292 | { | ||
293 | // Do it as a fullscreen modal dialog | ||
294 | PasswdDlg pd(0,0,TRUE,TRUE); | ||
295 | |||
296 | // see if there is contact information. | ||
297 | OwnerDlg *oi = 0; | ||
298 | QString vfilename = Global::applicationFileName("addressbook", | ||
299 | "businesscard.vcf"); | ||
300 | if (QFile::exists(vfilename)) { | ||
301 | Contact c; | ||
302 | c = Contact::readVCard( vfilename )[0]; | ||
303 | |||
304 | oi = new OwnerDlg(0, 0, c, TRUE, TRUE); | ||
305 | } | ||
306 | |||
307 | pd.reset(); | ||
308 | pd.exec(); | ||
309 | while (qcrypt(pd.passw->text, "a0") != passcode) { | ||
310 | if (oi) | ||
311 | oi->exec(); | ||
312 | pd.reset(); | ||
313 | pd.exec(); | ||
314 | } | ||
315 | } else if ( at_poweron ) { | ||
316 | // refresh screen #### should probably be in caller | ||
317 | // Not needed (we took away the screen blacking) | ||
318 | //if ( qwsServer ) | ||
319 | //qwsServer->refresh(); | ||
320 | } | ||
321 | } | ||
322 | |||
323 | #include "password.moc" | ||