1 /* pinentrydialog.cpp - A secure KDE dialog for PIN entry.
2 * Copyright (C) 2002 Klarälvdalens Datakonsult AB
3 * Copyright (C) 2007 g10 Code GmbH
4 * Written by Steffen Hansen <steffen@klaralvdalens-datakonsult.se>.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <https://www.gnu.org/licenses/>.
18 * SPDX-License-Identifier: GPL-2.0+
19 */
20
21 #include <ntqlayout.h>
22 #include <ntqpushbutton.h>
23 #include <ntqlabel.h>
24 #include <ntqmessagebox.h>
25 #include <ntqprogressbar.h>
26 #include <ntqtooltip.h>
27
28 #include "secqlineedit.h"
29
30 #include "pinentrydialog.h"
31 #include "pinentry.h"
32
PinEntryDialog(TQWidget * parent,const char * name,bool modal,bool enable_quality_bar)33 PinEntryDialog::PinEntryDialog( TQWidget* parent, const char* name,
34 bool modal, bool enable_quality_bar )
35 : TQDialog( parent, name, modal, TQt::WStyle_StaysOnTop ), _grabbed( false ),
36 _disable_echo_allowed ( true )
37 {
38 TQBoxLayout* top = new TQVBoxLayout( this, 6 );
39 TQBoxLayout* upperLayout = new TQHBoxLayout( top );
40
41 _icon = new TQLabel( this );
42 _icon->setPixmap( TQMessageBox::standardIcon( TQMessageBox::Information ) );
43 upperLayout->addWidget( _icon );
44
45 TQBoxLayout* labelLayout = new TQVBoxLayout( upperLayout );
46
47 _error = new TQLabel( this );
48 labelLayout->addWidget( _error );
49
50 _desc = new TQLabel( this );
51 labelLayout->addWidget( _desc );
52
53 TQGridLayout* grid = new TQGridLayout( labelLayout );
54
55 _prompt = new TQLabel( this );
56 _prompt->setAlignment( TQt::AlignRight | TQt::AlignVCenter );
57 grid->addWidget( _prompt, 0, 0 );
58 _edit = new SecTQLineEdit( this );
59 _edit->setMaxLength( 256 );
60 _edit->setEchoMode( SecTQLineEdit::Password );
61 grid->addWidget( _edit, 0, 1 );
62
63 if (enable_quality_bar)
64 {
65 _quality_bar_label = new TQLabel( this );
66 _quality_bar_label->setAlignment( TQt::AlignRight | TQt::AlignVCenter );
67 grid->addWidget ( _quality_bar_label, 1, 0 );
68 _quality_bar = new TQProgressBar( this );
69 _quality_bar->setCenterIndicator( true );
70 grid->addWidget( _quality_bar, 1, 1 );
71 _have_quality_bar = true;
72 }
73 else
74 _have_quality_bar = false;
75
76 TQBoxLayout* l = new TQHBoxLayout( top );
77
78 _ok = new TQPushButton( tr("OK"), this );
79 _cancel = new TQPushButton( tr("Cancel"), this );
80
81 l->addWidget( _ok );
82 l->addStretch();
83 l->addWidget( _cancel );
84
85 _ok->setDefault(true);
86
87 connect( _ok, SIGNAL( clicked() ),
88 this, SIGNAL( accepted() ) );
89 connect( _cancel, SIGNAL( clicked() ),
90 this, SIGNAL( rejected() ) );
91 connect( _edit, SIGNAL( textModified(const SecTQString&) ),
92 this, SLOT( updateQuality(const SecTQString&) ) );
93 connect (_edit, SIGNAL (backspacePressed()),
94 this, SLOT (onBackspace ()));
95 connect (this, SIGNAL (accepted ()),
96 this, SLOT (accept ()));
97 connect (this, SIGNAL (rejected ()),
98 this, SLOT (reject ()));
99 _edit->setFocus();
100 }
101
paintEvent(TQPaintEvent * ev)102 void PinEntryDialog::paintEvent( TQPaintEvent* ev )
103 {
104 // Grab keyboard when widget is mapped to screen
105 // It might be a little weird to do it here, but it works!
106 if( !_grabbed ) {
107 _edit->grabKeyboard();
108 _grabbed = true;
109 }
110 TQDialog::paintEvent( ev );
111 }
112
hideEvent(TQHideEvent * ev)113 void PinEntryDialog::hideEvent( TQHideEvent* ev )
114 {
115 _edit->releaseKeyboard();
116 _grabbed = false;
117 TQDialog::hideEvent( ev );
118 }
119
keyPressEvent(TQKeyEvent * e)120 void PinEntryDialog::keyPressEvent( TQKeyEvent* e )
121 {
122 if ( e->state() == 0 && e->key() == Key_Escape ) {
123 emit rejected();
124 return;
125 }
126 TQDialog::keyPressEvent( e );
127 }
128
129
updateQuality(const SecTQString & txt)130 void PinEntryDialog::updateQuality( const SecTQString & txt )
131 {
132 char *pin;
133 int length;
134 int percent;
135 TQPalette pal;
136
137 _disable_echo_allowed = false;
138
139 if (!_have_quality_bar || !_pinentry_info)
140 return;
141 pin = (char*)txt.utf8();
142 length = strlen (pin);
143 percent = length? pinentry_inq_quality (_pinentry_info, pin, length) : 0;
144 ::secmem_free (pin);
145 if (!length)
146 {
147 _quality_bar->reset ();
148 }
149 else
150 {
151 pal = _quality_bar->palette ();
152 if (percent < 0)
153 {
154 pal.setColor (TQColorGroup::Highlight, TQColor("red"));
155 percent = -percent;
156 }
157 else
158 {
159 pal.setColor (TQColorGroup::Highlight, TQColor("green"));
160 }
161 _quality_bar->setPalette (pal);
162 _quality_bar->setProgress (percent);
163 }
164 }
165
166
onBackspace()167 void PinEntryDialog::onBackspace()
168 {
169 if (_disable_echo_allowed)
170 _edit->setEchoMode( SecTQLineEdit::NoEcho );
171 }
172
173
setDescription(const TQString & txt)174 void PinEntryDialog::setDescription( const TQString& txt )
175 {
176 _desc->setText( txt );
177 _icon->setPixmap( TQMessageBox::standardIcon( TQMessageBox::Information ) );
178 setError( TQString::null );
179 }
180
description() const181 TQString PinEntryDialog::description() const
182 {
183 return _desc->text();
184 }
185
setError(const TQString & txt)186 void PinEntryDialog::setError( const TQString& txt )
187 {
188 if ( !txt.isNull() )
189 _icon->setPixmap( TQMessageBox::standardIcon( TQMessageBox::Critical ) );
190 _error->setText( txt );
191 }
192
error() const193 TQString PinEntryDialog::error() const
194 {
195 return _error->text();
196 }
197
setText(const SecTQString & txt)198 void PinEntryDialog::setText( const SecTQString& txt )
199 {
200 _edit->setText( txt );
201 }
202
text() const203 SecTQString PinEntryDialog::text() const
204 {
205 return _edit->text();
206 }
207
setPrompt(const TQString & txt)208 void PinEntryDialog::setPrompt( const TQString& txt )
209 {
210 _prompt->setText( txt );
211 if (txt.contains("PIN"))
212 _disable_echo_allowed = false;
213 }
214
prompt() const215 TQString PinEntryDialog::prompt() const
216 {
217 return _prompt->text();
218 }
219
setOkText(const TQString & txt)220 void PinEntryDialog::setOkText( const TQString& txt )
221 {
222 _ok->setText( txt );
223 }
224
setCancelText(const TQString & txt)225 void PinEntryDialog::setCancelText( const TQString& txt )
226 {
227 _cancel->setText( txt );
228 }
229
setQualityBar(const TQString & txt)230 void PinEntryDialog::setQualityBar( const TQString& txt )
231 {
232 if (_have_quality_bar)
233 _quality_bar_label->setText( txt );
234 }
235
setQualityBarTT(const TQString & txt)236 void PinEntryDialog::setQualityBarTT( const TQString& txt )
237 {
238 if (_have_quality_bar)
239 TQToolTip::add ( _quality_bar, txt );
240 }
241
setPinentryInfo(pinentry_t peinfo)242 void PinEntryDialog::setPinentryInfo (pinentry_t peinfo )
243 {
244 _pinentry_info = peinfo;
245 }
246
247 #include "pinentrydialog.moc"
248