00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "pin.h"
00025 #include "pinDialogBase.h"
00026
00027 #include <opie2/odebug.h>
00028 #include <opie2/oapplication.h>
00029
00030 #include <qpe/config.h>
00031 #include <qlabel.h>
00032 #include <qlineedit.h>
00033 #include <qtextview.h>
00034 #include <qstring.h>
00035 #include <qdialog.h>
00036
00037 #include <unistd.h>
00038 #include <stdlib.h>
00039 #include <time.h>
00040
00041 extern "C" char *crypt(const char *key, const char *salt);
00042
00043 using Opie::Security::MultiauthConfigWidget;
00044 using Opie::Security::MultiauthPluginObject;
00045
00047 static bool isSkip = FALSE;
00048
00050
00056 class PinDialog : public PinDialogBase
00057 {
00058 Q_OBJECT
00059
00060 public:
00061 PinDialog( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
00062 ~PinDialog();
00063
00064 void clear();
00065 void setPrompt( const QString& );
00066
00067 signals:
00069 void passwordEntered( const QString& );
00071 void skip();
00072
00073 protected:
00074 bool eventFilter( QObject*, QEvent* );
00075
00076 private:
00077 void input( QString );
00078 friend class PinPlugin;
00079 QString text;
00080 };
00081
00082
00084 PinDialog::PinDialog( QWidget* parent, const char* name, WFlags fl )
00085 : PinDialogBase( parent, name, fl )
00086 {
00087 QRect desk = oApp->desktop()->geometry();
00088
00089 if ( desk.width() < 220 ) {
00090 QFont f( font() );
00091 f.setPointSize( 18 );
00092 setFont( f );
00093 f.setPointSize( 12 );
00094 prompt->setFont( f );
00095 }
00096
00097 button_0->installEventFilter( this );
00098 button_1->installEventFilter( this );
00099 button_2->installEventFilter( this );
00100 button_3->installEventFilter( this );
00101 button_4->installEventFilter( this );
00102 button_5->installEventFilter( this );
00103 button_6->installEventFilter( this );
00104 button_7->installEventFilter( this );
00105 button_8->installEventFilter( this );
00106 button_9->installEventFilter( this );
00107 button_Skip->installEventFilter( this );
00108 button_OK->installEventFilter( this );
00109 setFocus();
00110 }
00111
00113 PinDialog::~PinDialog()
00114 {
00115
00116 }
00117
00119 bool PinDialog::eventFilter( QObject*o, QEvent*e )
00120 {
00121 if ( e->type() == QEvent::MouseButtonRelease ) {
00122 if ( o == button_OK ) {
00123 emit passwordEntered( text );
00124 }
00125 else if ( o == button_Skip ) {
00126 isSkip = TRUE;
00127 emit skip();
00128 }
00129 else {
00130 QLabel *l = (QLabel*)o;
00131 input(l->text());
00132 }
00133 }
00134 return FALSE;
00135 }
00136
00137 void PinDialog::input( QString c )
00138 {
00139 text += c;
00140 display->setText( text );
00141 }
00142
00143 void PinDialog::setPrompt( const QString& s )
00144 {
00145 prompt->setText( s );
00146 }
00147
00148 void PinDialog::clear()
00149 {
00150 text = "";
00151 input("");
00152 }
00153
00155
00159 class PinDlg : public QDialog
00160 {
00161 public:
00162 PinDlg( QWidget *parent, const char * name, bool modal, bool fullscreen = FALSE )
00163 : QDialog( parent, name, modal, fullscreen ? WStyle_NoBorder | WStyle_Customize | WStyle_StaysOnTop : 0 ),
00164 modl(modal)
00165 {
00166 pinD = new PinDialog( this );
00167
00168 if ( fullscreen ) {
00169 QRect desk = oApp->desktop()->geometry();
00170 setGeometry( 0, 0, desk.width(), desk.height() );
00171 }
00172
00173 connect( pinD, SIGNAL(passwordEntered(const QString&)),
00174 this, SLOT(accept()) );
00175 connect( pinD, SIGNAL(skip()), this, SLOT(accept()) );
00176 }
00177
00178 void resizeEvent( QResizeEvent * )
00179 {
00180 pinD->resize( size() );
00181 }
00182
00183 void reset()
00184 {
00185 pinD->clear();
00186 }
00187
00189 void accept()
00190 {
00191 if ( !modl )
00192 oApp->exit_loop();
00193 QDialog::accept();
00194 }
00195
00196 PinDialog *pinD;
00197 bool modl;
00198 };
00199
00201 QString PinPlugin::encrypt(const QString& pin)
00202 {
00203
00204 char salt[] = "$1$........";
00205 const char *const seedchars = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
00206
00207 srandom(time(0));
00208 int i;
00209 for(i = 0; i < 8; i++)
00210 {
00211
00212 salt[i+3] = seedchars[random() % 64];
00213 }
00214 return QString::fromLatin1(crypt(pin.latin1(),salt));
00215 }
00216
00218
00221 bool PinPlugin::verify(const QString& pin, const QString& hash)
00222 {
00223
00224 return hash.compare( QString::fromLatin1(crypt( pin.latin1(), hash.latin1() )) ) == 0 ? true : false;
00225 }
00226
00228
00233 QString PinPlugin::getPIN( const QString& prompt )
00234 {
00235 PinDlg pd(0,0,TRUE);
00236 pd.pinD->setPrompt( prompt );
00237
00238 pd.showMaximized();
00239 int r = pd.exec();
00240
00241 if ( r == QDialog::Accepted ) {
00242 if (pd.pinD->text.isEmpty())
00243 return "";
00244 else
00245 return pd.pinD->text;
00246 }
00247 else
00248 return QString::null;
00249 }
00250
00252
00256 QString PinPlugin::getCryptedPIN( const QString& prompt )
00257 {
00258 return encrypt(getPIN(prompt));
00259 }
00260
00262
00265 void PinPlugin::changePIN()
00266 {
00267 QString new1, new2;
00268 do {
00269 new1 = getPIN(QObject::tr("Enter new PIN"));
00270 if ( new1.isNull() )
00271 return;
00272 new2 = getPIN(QObject::tr("Re-enter new PIN"));
00273 } while (new1 != new2);
00274
00275 odebug << "writing new PIN hash in Security.conf" << oendl;
00276 Config cfg("Security");
00277 cfg.setGroup("PinPlugin");
00278 cfg.writeEntry("hashedPIN", encrypt(new1));
00279 }
00280
00282 void PinPlugin::clearPIN()
00283 {
00284 Config cfg("Security");
00285 cfg.setGroup("PinPlugin");
00286 cfg.removeEntry("hashedPIN");
00287 }
00288
00290
00293 int PinPlugin::authenticate()
00294 {
00295
00296 isSkip = FALSE;
00297
00298 Config cfg("Security");
00299 cfg.setGroup("PinPlugin");
00300 QString hashedPin = cfg.readEntry("hashedPIN");
00301 if (!hashedPin.isEmpty())
00302 {
00303
00304 PinDlg pd(0,0,TRUE,TRUE);
00305 pd.reset();
00306 pd.exec();
00307
00308
00309 if (isSkip == TRUE)
00310 return MultiauthPluginObject::Skip;
00311 else if (verify(pd.pinD->text, hashedPin))
00312 return MultiauthPluginObject::Success;
00313 else
00314 return MultiauthPluginObject::Failure;
00315 }
00316 owarn << "No PIN has been defined! We consider it as a successful authentication though." << oendl;
00317 return MultiauthPluginObject::Success;
00318 }
00319
00321 PinPlugin::PinPlugin() : MultiauthPluginObject(), m_pinW(0) {
00322 }
00323
00325 PinPlugin::~PinPlugin() {
00326 if (m_pinW != 0)
00327 delete m_pinW;
00328 }
00329
00331 QString PinPlugin::pluginName() const {
00332 return "PIN Plugin";
00333 }
00334
00335 QString PinPlugin::pixmapNameWidget() const {
00336 return "security/pinplugin";
00337 }
00338
00339 QString PinPlugin::pixmapNameConfig() const {
00340 return "security/pinplugin";
00341 }
00342
00344 MultiauthConfigWidget * PinPlugin::configWidget(QWidget * parent) {
00345 if (m_pinW == 0) {
00346 m_pinW = new PinConfigWidget(parent, "PIN configuration widget");
00347
00348 connect(m_pinW->changePIN, SIGNAL( clicked() ), this, SLOT( changePIN() ));
00349 connect(m_pinW->clearPIN, SIGNAL( clicked() ), this, SLOT( clearPIN() ));
00350 }
00351 return m_pinW;
00352 }
00353
00354 #include "pin.moc"
00355