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