~ubuntu-branches/ubuntu/maverick/kdebase-workspace/maverick-proposed

« back to all changes in this revision

Viewing changes to kdm/kfrontend/kgverify.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2010-07-08 01:11:52 UTC
  • mfrom: (1.1.43 upstream)
  • Revision ID: james.westby@ubuntu.com-20100708011152-z0h26httnjr91mmy
Tags: 4:4.4.92-0ubuntu1
* New upstream rc release:
  - Bump kde-sc-dev-latest to 4.4.92
  - Refresh patches
  - Update symbols
  - plasma-widgets-workspace replaces/conflicts plasma-widget-logout

Show diffs side-by-side

added added

removed removed

Lines of Context:
62
62
{
63
63
}
64
64
 
65
 
void KGVerifyHandler::updateStatus( bool, bool, int )
 
65
void KGVerifyHandler::updateStatus(bool, bool, int)
66
66
{
67
67
}
68
68
 
69
 
KGVerify::KGVerify( KGVerifyHandler *_handler,
70
 
                    QWidget *_parent, QWidget *_predecessor,
71
 
                    const QString &_fixedUser,
72
 
                    const PluginList &_pluginList,
73
 
                    KGreeterPlugin::Function _func,
74
 
                    KGreeterPlugin::Context _ctx )
75
 
        : inherited()
76
 
        , coreState( CoreIdle )
77
 
        , fixedEntity( _fixedUser )
78
 
        , pluginList( _pluginList )
79
 
        , handler( _handler )
80
 
        , parent( _parent )
81
 
        , predecessor( _predecessor )
82
 
        , plugMenu( 0 )
83
 
        , curPlugin( -1 )
84
 
        , timedLeft( 0 )
85
 
        , func( _func )
86
 
        , ctx( _ctx )
87
 
        , enabled( true )
88
 
        , running( false )
89
 
        , suspended( false )
90
 
        , failed( false )
91
 
        , isClear( true )
 
69
KGVerify::KGVerify(KGVerifyHandler *_handler,
 
70
                   QWidget *_parent, QWidget *_predecessor,
 
71
                   const QString &_fixedUser,
 
72
                   const PluginList &_pluginList,
 
73
                   KGreeterPlugin::Function _func,
 
74
                   KGreeterPlugin::Context _ctx)
 
75
    : inherited()
 
76
    , coreState(CoreIdle)
 
77
    , fixedEntity(_fixedUser)
 
78
    , pluginList(_pluginList)
 
79
    , handler(_handler)
 
80
    , parent(_parent)
 
81
    , predecessor(_predecessor)
 
82
    , plugMenu(0)
 
83
    , curPlugin(-1)
 
84
    , timedLeft(0)
 
85
    , func(_func)
 
86
    , ctx(_ctx)
 
87
    , enabled(true)
 
88
    , running(false)
 
89
    , suspended(false)
 
90
    , failed(false)
 
91
    , isClear(true)
92
92
{
93
 
        sockNot = new QSocketNotifier( rfd, QSocketNotifier::Read, this );
94
 
        sockNot->setEnabled( false );
95
 
        connect( sockNot, SIGNAL(activated( int )), SLOT(handleVerify()) );
96
 
 
97
 
        connect( &timer, SIGNAL(timeout()), SLOT(slotTimeout()) );
98
 
        connect( qApp, SIGNAL(activity()), SLOT(slotActivity()) );
99
 
 
100
 
        _parent->installEventFilter( this );
 
93
    sockNot = new QSocketNotifier(rfd, QSocketNotifier::Read, this);
 
94
    sockNot->setEnabled(false);
 
95
    connect(sockNot, SIGNAL(activated(int)), SLOT(handleVerify()));
 
96
 
 
97
    connect(&timer, SIGNAL(timeout()), SLOT(slotTimeout()));
 
98
    connect(qApp, SIGNAL(activity()), SLOT(slotActivity()));
 
99
 
 
100
    _parent->installEventFilter(this);
101
101
}
102
102
 
103
103
KGVerify::~KGVerify()
104
104
{
105
 
        debug( "delete %s\n", pName.data() );
106
 
        delete greet;
 
105
    debug("delete %s\n", pName.data());
 
106
    delete greet;
107
107
}
108
108
 
109
109
QMenu *
110
110
KGVerify::getPlugMenu()
111
111
{
112
 
        // assert( coreState != CoreBusy );
113
 
        if (!plugMenu) {
114
 
                uint np = pluginList.count();
115
 
                if (np > 1) {
116
 
                        plugMenu = new QMenu( parent );
117
 
                        QActionGroup *plugGroup = new QActionGroup( parent );
118
 
                        connect( plugMenu, SIGNAL(triggered( QAction * )),
119
 
                                 SLOT(slotPluginSelected( QAction * )) );
120
 
                        for (uint i = 0; i < np; i++) {
121
 
                                int pid = pluginList[i];
122
 
                                greetPlugins[pid].action = plugGroup->addAction(
123
 
                                        i18nc("@item:inmenu authentication method",
124
 
                                              greetPlugins[pid].info->name) );
125
 
                                greetPlugins[pid].action->setData( i );
126
 
                                greetPlugins[pid].action->setCheckable( true );
127
 
                        }
128
 
                        plugMenu->addActions( plugGroup->actions() );
129
 
                }
130
 
        }
131
 
        return plugMenu;
 
112
    // assert(coreState != CoreBusy);
 
113
    if (!plugMenu) {
 
114
        uint np = pluginList.count();
 
115
        if (np > 1) {
 
116
            plugMenu = new QMenu(parent);
 
117
            QActionGroup *plugGroup = new QActionGroup(parent);
 
118
            connect(plugMenu, SIGNAL(triggered(QAction *)),
 
119
                    SLOT(slotPluginSelected(QAction *)));
 
120
            for (uint i = 0; i < np; i++) {
 
121
                int pid = pluginList[i];
 
122
                greetPlugins[pid].action = plugGroup->addAction(
 
123
                    i18nc("@item:inmenu authentication method",
 
124
                          greetPlugins[pid].info->name));
 
125
                greetPlugins[pid].action->setData(i);
 
126
                greetPlugins[pid].action->setCheckable(true);
 
127
            }
 
128
            plugMenu->addActions(plugGroup->actions());
 
129
        }
 
130
    }
 
131
    return plugMenu;
132
132
}
133
133
 
134
134
bool // public
135
135
KGVerify::entitiesLocal() const
136
136
{
137
 
        return greetPlugins[pluginList[curPlugin]].info->flags & KGreeterPluginInfo::Local;
 
137
    return greetPlugins[pluginList[curPlugin]].info->flags & KGreeterPluginInfo::Local;
138
138
}
139
139
 
140
140
bool // public
141
141
KGVerify::entitiesFielded() const
142
142
{
143
 
        return greetPlugins[pluginList[curPlugin]].info->flags & KGreeterPluginInfo::Fielded;
 
143
    return greetPlugins[pluginList[curPlugin]].info->flags & KGreeterPluginInfo::Fielded;
144
144
}
145
145
 
146
146
bool // public
147
147
KGVerify::entityPresettable() const
148
148
{
149
 
        return greetPlugins[pluginList[curPlugin]].info->flags & KGreeterPluginInfo::Presettable;
 
149
    return greetPlugins[pluginList[curPlugin]].info->flags & KGreeterPluginInfo::Presettable;
150
150
}
151
151
 
152
152
bool // public
153
153
KGVerify::isClassic() const
154
154
{
155
 
        return !strcmp( greetPlugins[pluginList[curPlugin]].info->method, "classic" );
 
155
    return !strcmp(greetPlugins[pluginList[curPlugin]].info->method, "classic");
156
156
}
157
157
 
158
158
QString // public
159
159
KGVerify::pluginName() const
160
160
{
161
 
        QString name( greetPlugins[pluginList[curPlugin]].library->fileName() );
162
 
        uint st = name.lastIndexOf( '/' ) + 1;
163
 
        uint en = name.indexOf( '.', st );
164
 
        if (en - st > 7 && QString::fromRawData( name.unicode() + st, 7 ) == QLatin1String("kgreet_"))
165
 
                st += 7;
166
 
        return name.mid( st, en - st );
 
161
    QString name(greetPlugins[pluginList[curPlugin]].library->fileName());
 
162
    uint st = name.lastIndexOf('/') + 1;
 
163
    uint en = name.indexOf('.', st);
 
164
    if (en - st > 7 && QString::fromRawData(name.unicode() + st, 7) == QLatin1String("kgreet_"))
 
165
        st += 7;
 
166
    return name.mid(st, en - st);
167
167
}
168
168
 
169
169
static void
170
 
setTabOrder( QWidget *&pred, const QObjectList &list )
 
170
setTabOrder(QWidget *&pred, const QObjectList &list)
171
171
{
172
 
        foreach (QObject *o, list)
173
 
                if (QWidget *w = qobject_cast<QWidget *>(o)) {
174
 
                        if (w->focusPolicy() & Qt::TabFocus) {
175
 
                                QWidget::setTabOrder( pred, w );
176
 
                                pred = w;
177
 
                        } else
178
 
                                setTabOrder( pred, o->children() );
179
 
                }
 
172
    foreach (QObject *o, list)
 
173
        if (QWidget *w = qobject_cast<QWidget *>(o)) {
 
174
            if (w->focusPolicy() & Qt::TabFocus) {
 
175
                QWidget::setTabOrder(pred, w);
 
176
                pred = w;
 
177
            } else {
 
178
                setTabOrder(pred, o->children());
 
179
            }
 
180
        }
180
181
}
181
182
 
182
183
void // public
183
 
KGVerify::selectPlugin( int id )
 
184
KGVerify::selectPlugin(int id)
184
185
{
185
 
        if (pluginList.isEmpty()) {
186
 
                msgBox( errorbox, i18n("No greeter widget plugin loaded. Check the configuration.") );
187
 
                ::exit( EX_UNMANAGE_DPY );
188
 
        }
189
 
        curPlugin = id;
190
 
        if (plugMenu)
191
 
                greetPlugins[pluginList[id]].action->setChecked( true );
192
 
        pName = ("greet_" + pluginName()).toLatin1();
193
 
        debug( "new %s\n", pName.data() );
194
 
        greet = greetPlugins[pluginList[id]].info->create( this, parent, fixedEntity, func, ctx );
195
 
        if (QWidget *pred = predecessor)
196
 
                setTabOrder( pred, *(const QObjectList *)&greet->getWidgets() );
197
 
        timeable = _autoLoginDelay && entityPresettable() && isClassic();
 
186
    if (pluginList.isEmpty()) {
 
187
        msgBox(errorbox, i18n("No greeter widget plugin loaded. Check the configuration."));
 
188
        ::exit(EX_UNMANAGE_DPY);
 
189
    }
 
190
    curPlugin = id;
 
191
    if (plugMenu)
 
192
        greetPlugins[pluginList[id]].action->setChecked(true);
 
193
    pName = ("greet_" + pluginName()).toLatin1();
 
194
    debug("new %s\n", pName.data());
 
195
    greet = greetPlugins[pluginList[id]].info->create(this, parent, fixedEntity, func, ctx);
 
196
    if (QWidget *pred = predecessor)
 
197
        setTabOrder(pred, *(const QObjectList *)&greet->getWidgets());
 
198
    timeable = _autoLoginDelay && entityPresettable() && isClassic();
198
199
}
199
200
 
200
201
void // private slot
201
 
KGVerify::slotPluginSelected( QAction *action )
202
 
{
203
 
        if (failed)
204
 
                return;
205
 
        int id = action->data().toInt();
206
 
        if (id != curPlugin) {
207
 
                parent->setUpdatesEnabled( false );
208
 
                debug( "delete %s\n", pName.data() );
209
 
                delete greet;
210
 
                selectPlugin( id );
211
 
                handler->verifyPluginChanged( id );
212
 
                if (running)
213
 
                        start();
214
 
                parent->setUpdatesEnabled( true );
215
 
        }
216
 
}
217
 
 
218
 
void // public
219
 
KGVerify::loadUsers( const QStringList &users )
220
 
{
221
 
        debug( "%s->loadUsers(...)\n", pName.data() );
222
 
        greet->loadUsers( users );
223
 
}
224
 
 
225
 
void // public
226
 
KGVerify::presetEntity( const QString &entity, int field )
227
 
{
228
 
        presEnt = entity;
229
 
        presFld = field;
 
202
KGVerify::slotPluginSelected(QAction *action)
 
203
{
 
204
    if (failed)
 
205
        return;
 
206
    int id = action->data().toInt();
 
207
    if (id != curPlugin) {
 
208
        parent->setUpdatesEnabled(false);
 
209
        debug("delete %s\n", pName.data());
 
210
        delete greet;
 
211
        selectPlugin(id);
 
212
        handler->verifyPluginChanged(id);
 
213
        if (running)
 
214
            start();
 
215
        parent->setUpdatesEnabled(true);
 
216
    }
 
217
}
 
218
 
 
219
void // public
 
220
KGVerify::loadUsers(const QStringList &users)
 
221
{
 
222
    debug("%s->loadUsers(...)\n", pName.data());
 
223
    greet->loadUsers(users);
 
224
}
 
225
 
 
226
void // public
 
227
KGVerify::presetEntity(const QString &entity, int field)
 
228
{
 
229
    presEnt = entity;
 
230
    presFld = field;
230
231
}
231
232
 
232
233
bool // private
233
234
KGVerify::applyPreset()
234
235
{
235
 
        if (!presEnt.isEmpty()) {
236
 
                debug( "%s->presetEntity(%\"s, %d)\n", pName.data(),
237
 
                       qPrintable( presEnt ), presFld );
238
 
                greet->presetEntity( presEnt, presFld );
239
 
                if (entitiesLocal()) {
240
 
                        curUser = presEnt;
241
 
                        pamUser.clear();
242
 
                        handler->verifySetUser( presEnt );
243
 
                }
244
 
                return true;
245
 
        }
246
 
        return false;
 
236
    if (!presEnt.isEmpty()) {
 
237
        debug("%s->presetEntity(%\"s, %d)\n", pName.data(),
 
238
              qPrintable(presEnt), presFld);
 
239
        greet->presetEntity(presEnt, presFld);
 
240
        if (entitiesLocal()) {
 
241
            curUser = presEnt;
 
242
            pamUser.clear();
 
243
            handler->verifySetUser(presEnt);
 
244
        }
 
245
        return true;
 
246
    }
 
247
    return false;
247
248
}
248
249
 
249
250
bool // private
250
 
KGVerify::scheduleAutoLogin( bool initial )
 
251
KGVerify::scheduleAutoLogin(bool initial)
251
252
{
252
 
        if (timeable) {
253
 
                debug( "%s->presetEntity(%\"s, -1)\n", pName.data(),
254
 
                       qPrintable( _autoLoginUser ), -1 );
255
 
                greet->presetEntity( _autoLoginUser, -1 );
256
 
                curUser = _autoLoginUser;
257
 
                handler->verifySetUser( _autoLoginUser );
258
 
                timer.start( 1000 );
259
 
                if (initial) {
260
 
                        timedLeft = _autoLoginDelay;
261
 
                        deadTicks = 0;
262
 
                } else {
263
 
                        timedLeft = qMax( _autoLoginDelay - TIMED_GREET_TO, MIN_TIMED_TO );
264
 
                        deadTicks = DEAD_TIMED_TO;
265
 
                }
266
 
                updateStatus();
267
 
                sockNot->setEnabled( false );
268
 
                running = false;
269
 
                isClear = true;
270
 
                return true;
271
 
        }
272
 
        return false;
 
253
    if (timeable) {
 
254
        debug("%s->presetEntity(%\"s, -1)\n", pName.data(),
 
255
              qPrintable(_autoLoginUser), -1);
 
256
        greet->presetEntity(_autoLoginUser, -1);
 
257
        curUser = _autoLoginUser;
 
258
        handler->verifySetUser(_autoLoginUser);
 
259
        timer.start(1000);
 
260
        if (initial) {
 
261
            timedLeft = _autoLoginDelay;
 
262
            deadTicks = 0;
 
263
        } else {
 
264
            timedLeft = qMax(_autoLoginDelay - TIMED_GREET_TO, MIN_TIMED_TO);
 
265
            deadTicks = DEAD_TIMED_TO;
 
266
        }
 
267
        updateStatus();
 
268
        sockNot->setEnabled(false);
 
269
        running = false;
 
270
        isClear = true;
 
271
        return true;
 
272
    }
 
273
    return false;
273
274
}
274
275
 
275
276
void // private
276
277
KGVerify::performAutoLogin()
277
278
{
278
 
//      timer.stop();
279
 
        gSendInt( G_AutoLogin );
280
 
        coreState = CoreBusy;
 
279
//    timer.stop();
 
280
    gSendInt(G_AutoLogin);
 
281
    coreState = CoreBusy;
281
282
}
282
283
 
283
284
QString // public
284
285
KGVerify::getEntity() const
285
286
{
286
 
        debug( "%s->getEntity()\n", pName.data() );
287
 
        QString ent = greet->getEntity();
288
 
        debug( "  entity: %s\n", qPrintable( ent ) );
289
 
        return ent;
 
287
    debug("%s->getEntity()\n", pName.data());
 
288
    QString ent = greet->getEntity();
 
289
    debug("  entity: %s\n", qPrintable(ent));
 
290
    return ent;
290
291
}
291
292
 
292
293
void
293
 
KGVerify::setUser( const QString &user )
 
294
KGVerify::setUser(const QString &user)
294
295
{
295
 
        // assert( fixedEntity.isEmpty() );
296
 
        curUser = user;
297
 
        debug( "%s->setUser(%\"s)\n", pName.data(), qPrintable( user ) );
298
 
        greet->setUser( user );
299
 
        talkerEdits();
 
296
    // assert(fixedEntity.isEmpty());
 
297
    curUser = user;
 
298
    debug("%s->setUser(%\"s)\n", pName.data(), qPrintable(user));
 
299
    greet->setUser(user);
 
300
    talkerEdits();
300
301
}
301
302
 
302
303
void
303
304
KGVerify::start()
304
305
{
305
 
        authTok = (func == KGreeterPlugin::ChAuthTok);
306
 
        if (func == KGreeterPlugin::Authenticate && ctx == KGreeterPlugin::Login) {
307
 
                if (scheduleAutoLogin( true )) {
308
 
                        if (!_autoLoginAgain)
309
 
                                _autoLoginDelay = 0, timeable = false;
310
 
                        return;
311
 
                } else
312
 
                        applyPreset();
313
 
        }
314
 
        sockNot->setEnabled( true );
315
 
        running = true;
316
 
        if (!(func == KGreeterPlugin::Authenticate ||
317
 
              ctx == KGreeterPlugin::ChangeTok ||
318
 
              ctx == KGreeterPlugin::ExChangeTok))
319
 
        {
320
 
                coreState = CoreBusy;
321
 
        }
322
 
        debug( "%s->start()\n", pName.data() );
323
 
        greet->start();
 
306
    authTok = (func == KGreeterPlugin::ChAuthTok);
 
307
    if (func == KGreeterPlugin::Authenticate && ctx == KGreeterPlugin::Login) {
 
308
        if (scheduleAutoLogin(true)) {
 
309
            if (!_autoLoginAgain)
 
310
                _autoLoginDelay = 0, timeable = false;
 
311
            return;
 
312
        } else {
 
313
            applyPreset();
 
314
        }
 
315
    }
 
316
    sockNot->setEnabled(true);
 
317
    running = true;
 
318
    if (!(func == KGreeterPlugin::Authenticate ||
 
319
          ctx == KGreeterPlugin::ChangeTok ||
 
320
          ctx == KGreeterPlugin::ExChangeTok))
 
321
    {
 
322
        coreState = CoreBusy;
 
323
    }
 
324
    debug("%s->start()\n", pName.data());
 
325
    greet->start();
324
326
}
325
327
 
326
328
void
327
329
KGVerify::abort()
328
330
{
329
 
        debug( "%s->abort()\n", pName.data() );
330
 
        greet->abort();
331
 
        sockNot->setEnabled( false );
332
 
        running = false;
 
331
    debug("%s->abort()\n", pName.data());
 
332
    greet->abort();
 
333
    sockNot->setEnabled(false);
 
334
    running = false;
333
335
}
334
336
 
335
337
void
336
338
KGVerify::suspend()
337
339
{
338
 
        // assert( coreState != CoreBusy );
339
 
        if (running) {
340
 
                debug( "%s->abort()\n", pName.data() );
341
 
                greet->abort();
342
 
        }
343
 
        suspended = true;
344
 
        updateStatus();
345
 
        timer.suspend();
346
 
        sockNot->setEnabled( false );
 
340
    // assert(coreState != CoreBusy);
 
341
    if (running) {
 
342
        debug("%s->abort()\n", pName.data());
 
343
        greet->abort();
 
344
    }
 
345
    suspended = true;
 
346
    updateStatus();
 
347
    timer.suspend();
 
348
    sockNot->setEnabled(false);
347
349
}
348
350
 
349
351
void
350
352
KGVerify::resume()
351
353
{
352
 
        sockNot->setEnabled( true );
353
 
        timer.resume();
354
 
        suspended = false;
355
 
        updateLockStatus();
356
 
        if (running) {
357
 
                debug( "%s->start()\n", pName.data() );
358
 
                greet->start();
359
 
        } else if (delayed) {
360
 
                delayed = false;
361
 
                running = true;
362
 
                sockNot->setEnabled( true );
363
 
                debug( "%s->start()\n", pName.data() );
364
 
                greet->start();
365
 
        }
 
354
    sockNot->setEnabled(true);
 
355
    timer.resume();
 
356
    suspended = false;
 
357
    updateLockStatus();
 
358
    if (running) {
 
359
        debug("%s->start()\n", pName.data());
 
360
        greet->start();
 
361
    } else if (delayed) {
 
362
        delayed = false;
 
363
        running = true;
 
364
        sockNot->setEnabled(true);
 
365
        debug("%s->start()\n", pName.data());
 
366
        greet->start();
 
367
    }
366
368
}
367
369
 
368
370
void // not a slot - called manually by greeter
369
371
KGVerify::accept()
370
372
{
371
 
        debug( "%s->next()\n", pName.data() );
372
 
        greet->next();
 
373
    debug("%s->next()\n", pName.data());
 
374
    greet->next();
373
375
}
374
376
 
375
377
void // private
376
 
KGVerify::doReject( bool initial )
 
378
KGVerify::doReject(bool initial)
377
379
{
378
 
        // assert( coreState != CoreBusy );
379
 
        if (running) {
380
 
                debug( "%s->abort()\n", pName.data() );
381
 
                greet->abort();
382
 
        }
383
 
        handler->verifyClear();
384
 
        debug( "%s->clear()\n", pName.data() );
385
 
        greet->clear();
386
 
        curUser.clear();
387
 
        pamUser.clear();
388
 
        if (!scheduleAutoLogin( initial )) {
389
 
                isClear = !(isClear && applyPreset());
390
 
                if (running) {
391
 
                        debug( "%s->start()\n", pName.data() );
392
 
                        greet->start();
393
 
                }
394
 
                if (!failed)
395
 
                        timer.stop();
396
 
        }
 
380
    // assert(coreState != CoreBusy);
 
381
    if (running) {
 
382
        debug("%s->abort()\n", pName.data());
 
383
        greet->abort();
 
384
    }
 
385
    handler->verifyClear();
 
386
    debug("%s->clear()\n", pName.data());
 
387
    greet->clear();
 
388
    curUser.clear();
 
389
    pamUser.clear();
 
390
    if (!scheduleAutoLogin(initial)) {
 
391
        isClear = !(isClear && applyPreset());
 
392
        if (running) {
 
393
            debug("%s->start()\n", pName.data());
 
394
            greet->start();
 
395
        }
 
396
        if (!failed)
 
397
            timer.stop();
 
398
    }
397
399
}
398
400
 
399
401
void // not a slot - called manually by greeter
400
402
KGVerify::reject()
401
403
{
402
 
        doReject( true );
 
404
    doReject(true);
403
405
}
404
406
 
405
407
void
406
 
KGVerify::setEnabled( bool on )
 
408
KGVerify::setEnabled(bool on)
407
409
{
408
 
        debug( "%s->setEnabled(%s)\n", pName.data(), on ? "true" : "false" );
409
 
        greet->setEnabled( on );
410
 
        enabled = on;
411
 
        updateStatus();
 
410
    debug("%s->setEnabled(%s)\n", pName.data(), on ? "true" : "false");
 
411
    greet->setEnabled(on);
 
412
    enabled = on;
 
413
    updateStatus();
412
414
}
413
415
 
414
416
void // private
415
417
KGVerify::slotTimeout()
416
418
{
417
 
        if (failed) {
418
 
                failed = false;
419
 
                updateStatus();
420
 
                debug( "%s->revive()\n", pName.data() );
421
 
                greet->revive();
422
 
                handler->verifyRetry();
423
 
                if (suspended)
424
 
                        delayed = true;
425
 
                else {
426
 
                        running = true;
427
 
                        sockNot->setEnabled( true );
428
 
                        debug( "%s->start()\n", pName.data() );
429
 
                        greet->start();
430
 
                        slotActivity();
431
 
                        talkerEdits();
432
 
                }
433
 
        } else if (timedLeft) {
434
 
                deadTicks--;
435
 
                if (!--timedLeft)
436
 
                        performAutoLogin();
437
 
                else
438
 
                        timer.start( 1000 );
439
 
                updateStatus();
440
 
        } else {
441
 
                // assert( ctx == Login );
442
 
                isClear = true;
443
 
                doReject( false );
444
 
        }
 
419
    if (failed) {
 
420
        failed = false;
 
421
        updateStatus();
 
422
        debug("%s->revive()\n", pName.data());
 
423
        greet->revive();
 
424
        handler->verifyRetry();
 
425
        if (suspended) {
 
426
            delayed = true;
 
427
        } else {
 
428
            running = true;
 
429
            sockNot->setEnabled(true);
 
430
            debug("%s->start()\n", pName.data());
 
431
            greet->start();
 
432
            slotActivity();
 
433
            talkerEdits();
 
434
        }
 
435
    } else if (timedLeft) {
 
436
        deadTicks--;
 
437
        if (!--timedLeft)
 
438
            performAutoLogin();
 
439
        else
 
440
            timer.start(1000);
 
441
        updateStatus();
 
442
    } else {
 
443
        // assert(ctx == Login);
 
444
        isClear = true;
 
445
        doReject(false);
 
446
    }
445
447
}
446
448
 
447
449
void
448
450
KGVerify::slotActivity()
449
451
{
450
 
        if (timedLeft) {
451
 
                // timed login countdown running. cancel and reschedule it.
452
 
                debug( "%s->revive()\n", pName.data() );
453
 
                greet->revive();
454
 
                debug( "%s->start()\n", pName.data() );
455
 
                greet->start();
456
 
                sockNot->setEnabled( true );
457
 
                running = true;
458
 
                timedLeft = 0;
459
 
                updateStatus();
460
 
                timer.start( TIMED_GREET_TO * SECONDS );
461
 
        } else if (timeable)
462
 
                // timed login is possible and thus scheduled. reschedule it.
463
 
                timer.start( TIMED_GREET_TO * SECONDS );
 
452
    if (timedLeft) {
 
453
        // timed login countdown running. cancel and reschedule it.
 
454
        debug("%s->revive()\n", pName.data());
 
455
        greet->revive();
 
456
        debug("%s->start()\n", pName.data());
 
457
        greet->start();
 
458
        sockNot->setEnabled(true);
 
459
        running = true;
 
460
        timedLeft = 0;
 
461
        updateStatus();
 
462
        timer.start(TIMED_GREET_TO * SECONDS);
 
463
    } else if (timeable) {
 
464
        // timed login is possible and thus scheduled. reschedule it.
 
465
        timer.start(TIMED_GREET_TO * SECONDS);
 
466
    }
464
467
}
465
468
 
466
469
void
467
470
KGVerify::talkerEdits()
468
471
{
469
 
        if (func == KGreeterPlugin::Authenticate &&
470
 
            ctx == KGreeterPlugin::Login)
471
 
        {
472
 
                isClear = false;
473
 
                if (!timeable)
474
 
                        timer.start( FULL_GREET_TO * SECONDS );
475
 
        }
 
472
    if (func == KGreeterPlugin::Authenticate &&
 
473
        ctx == KGreeterPlugin::Login)
 
474
    {
 
475
        isClear = false;
 
476
        if (!timeable)
 
477
            timer.start(FULL_GREET_TO * SECONDS);
 
478
    }
476
479
}
477
480
 
478
481
 
479
482
void // private static
480
 
KGVerify::vrfMsgBox( QWidget *parent, const QString &user,
481
 
                     QMessageBox::Icon type, const QString &mesg )
 
483
KGVerify::vrfMsgBox(QWidget *parent, const QString &user,
 
484
                    QMessageBox::Icon type, const QString &mesg)
482
485
{
483
 
        KFMsgBox::box( parent, type, user.isEmpty() ?
484
 
                       mesg : i18n("Logging in %1...\n\n", user ) + mesg );
 
486
    KFMsgBox::box(parent, type, user.isEmpty() ?
 
487
                  mesg : i18n("Logging in %1...\n\n", user) + mesg);
485
488
}
486
489
 
487
 
static const char * const msgs[]= {
488
 
        I18N_NOOP( "You are required to change your password immediately (password aged)." ),
489
 
        I18N_NOOP( "You are required to change your password immediately (root enforced)." ),
490
 
        I18N_NOOP( "You are not allowed to login at the moment." ),
491
 
        I18N_NOOP( "Home folder not available." ),
492
 
        I18N_NOOP( "Logins are not allowed at the moment.\nTry again later." ),
493
 
        I18N_NOOP( "Your login shell is not listed in /etc/shells." ),
494
 
        I18N_NOOP( "Root logins are not allowed." ),
495
 
        I18N_NOOP( "Your account has expired; please contact your system administrator." )
 
490
static const char * const msgs[] = {
 
491
    I18N_NOOP("You are required to change your password immediately (password aged)."),
 
492
    I18N_NOOP("You are required to change your password immediately (root enforced)."),
 
493
    I18N_NOOP("You are not allowed to login at the moment."),
 
494
    I18N_NOOP("Home folder not available."),
 
495
    I18N_NOOP("Logins are not allowed at the moment.\nTry again later."),
 
496
    I18N_NOOP("Your login shell is not listed in /etc/shells."),
 
497
    I18N_NOOP("Root logins are not allowed."),
 
498
    I18N_NOOP("Your account has expired; please contact your system administrator.")
496
499
};
497
500
 
498
501
void // private static
499
 
KGVerify::vrfErrBox( QWidget *parent, const QString &user, const char *msg )
 
502
KGVerify::vrfErrBox(QWidget *parent, const QString &user, const char *msg)
500
503
{
501
 
        QMessageBox::Icon icon;
502
 
        QString mesg;
 
504
    QMessageBox::Icon icon;
 
505
    QString mesg;
503
506
 
504
 
        if (!msg) {
505
 
                mesg = i18n("A critical error occurred.\n"
506
 
                            "Please look at KDM's logfile(s) for more information\n"
507
 
                            "or contact your system administrator.");
508
 
                icon = errorbox;
509
 
        } else {
510
 
                mesg = QString::fromLocal8Bit( msg );
511
 
                QString mesg1 = mesg + '.';
512
 
                for (uint i = 0; i < as(msgs); i++)
513
 
                        if (mesg1 == msgs[i]) {
514
 
                                mesg = i18n(msgs[i]);
515
 
                                break;
516
 
                        }
517
 
                icon = sorrybox;
518
 
        }
519
 
        vrfMsgBox( parent, user, icon, mesg );
 
507
    if (!msg) {
 
508
        mesg = i18n("A critical error occurred.\n"
 
509
                    "Please look at KDM's logfile(s) for more information\n"
 
510
                    "or contact your system administrator.");
 
511
        icon = errorbox;
 
512
    } else {
 
513
        mesg = QString::fromLocal8Bit(msg);
 
514
        QString mesg1 = mesg + '.';
 
515
        for (uint i = 0; i < as(msgs); i++)
 
516
            if (mesg1 == msgs[i]) {
 
517
                mesg = i18n(msgs[i]);
 
518
                break;
 
519
            }
 
520
        icon = sorrybox;
 
521
    }
 
522
    vrfMsgBox(parent, user, icon, mesg);
520
523
}
521
524
 
522
525
void // private static
523
 
KGVerify::vrfInfoBox( QWidget *parent, const QString &user, const char *msg )
 
526
KGVerify::vrfInfoBox(QWidget *parent, const QString &user, const char *msg)
524
527
{
525
 
        QString mesg = QString::fromLocal8Bit( msg );
526
 
        QRegExp rx( "^Warning: your account will expire in (\\d+) day" );
527
 
        if (rx.indexIn( mesg ) >= 0) {
528
 
                int expire = rx.cap( 1 ).toInt();
529
 
                mesg = expire ?
530
 
                        i18np("Your account expires tomorrow.",
531
 
                              "Your account expires in %1 days.", expire) :
532
 
                        i18n("Your account expires today.");
533
 
        } else {
534
 
                rx.setPattern( "^Warning: your password will expire in (\\d+) day" );
535
 
                if (rx.indexIn( mesg ) >= 0) {
536
 
                        int expire = rx.cap( 1 ).toInt();
537
 
                        mesg = expire ?
538
 
                                i18np("Your password expires tomorrow.",
539
 
                                      "Your password expires in %1 days.", expire) :
540
 
                                i18n("Your password expires today.");
541
 
                }
542
 
        }
543
 
        vrfMsgBox( parent, user, infobox, mesg );
 
528
    QString mesg = QString::fromLocal8Bit(msg);
 
529
    QRegExp rx("^Warning: your account will expire in (\\d+) day");
 
530
    if (rx.indexIn(mesg) >= 0) {
 
531
        int expire = rx.cap(1).toInt();
 
532
        mesg = expire ?
 
533
            i18np("Your account expires tomorrow.",
 
534
                  "Your account expires in %1 days.", expire) :
 
535
            i18n("Your account expires today.");
 
536
    } else {
 
537
        rx.setPattern("^Warning: your password will expire in (\\d+) day");
 
538
        if (rx.indexIn(mesg) >= 0) {
 
539
            int expire = rx.cap(1).toInt();
 
540
            mesg = expire ?
 
541
                i18np("Your password expires tomorrow.",
 
542
                      "Your password expires in %1 days.", expire) :
 
543
                i18n("Your password expires today.");
 
544
        }
 
545
    }
 
546
    vrfMsgBox(parent, user, infobox, mesg);
544
547
}
545
548
 
546
549
bool // public static
547
 
KGVerify::handleFailVerify( QWidget *parent, bool showUser )
 
550
KGVerify::handleFailVerify(QWidget *parent, bool showUser)
548
551
{
549
 
        char *msg;
550
 
        QString user;
551
 
 
552
 
        debug( "handleFailVerify ...\n" );
553
 
 
554
 
        if (showUser) {
555
 
                msg = gRecvStr();
556
 
                user = QString::fromLocal8Bit( msg );
557
 
                free( msg );
558
 
        }
559
 
 
560
 
        for (;;) {
561
 
                int ret = gRecvInt();
562
 
 
563
 
                // non-terminal status
564
 
                switch (ret) {
565
 
                /* case V_PUT_USER: cannot happen - we are in "classic" mode */
566
 
                /* case V_PRE_OK: cannot happen - not in ChTok dialog */
567
 
                /* case V_CHTOK: cannot happen - called by non-interactive verify */
568
 
                case V_CHTOK_AUTH:
569
 
                        debug( " V_CHTOK_AUTH\n" );
570
 
                        {
571
 
                                QStringList pgs( _pluginsLogin );
572
 
                                pgs += _pluginsShutdown;
573
 
                                foreach (const QString& pg, pgs)
574
 
                                        if (pg == "classic" || pg == "modern") {
575
 
                                                pgs = QStringList( pg );
576
 
                                                goto gotit;
577
 
                                        } else if (pg == "generic") {
578
 
                                                pgs = QStringList( "modern" );
579
 
                                                goto gotit;
580
 
                                        }
581
 
                                pgs = QStringList( "classic" );
582
 
                          gotit:
583
 
                                KGChTok chtok( parent, user, init( pgs ), 0,
584
 
                                               KGreeterPlugin::AuthChAuthTok,
585
 
                                               KGreeterPlugin::Login );
586
 
                                return chtok.exec();
587
 
                        }
588
 
                case V_MSG_ERR:
589
 
                        debug( " V_MSG_ERR\n" );
590
 
                        msg = gRecvStr();
591
 
                        debug( "  message %\"s\n", msg );
592
 
                        vrfErrBox( parent, user, msg );
593
 
                        free( msg );
594
 
                        gSendInt( 0 );
595
 
                        continue;
596
 
                case V_MSG_INFO_AUTH: // should not happen
597
 
                case V_MSG_INFO:
598
 
                        debug( " V_MSG_INFO\n" );
599
 
                        msg = gRecvStr();
600
 
                        debug( "  message %\"s\n", msg );
601
 
                        vrfInfoBox( parent, user, msg );
602
 
                        free( msg );
603
 
                        gSendInt( 0 );
604
 
                        continue;
605
 
                }
606
 
 
607
 
                // terminal status
608
 
                switch (ret) {
609
 
                case V_OK:
610
 
                        debug( " V_OK\n" );
611
 
                        return true;
612
 
                case V_AUTH:
613
 
                        debug( " V_AUTH\n" );
614
 
                        vrfMsgBox( parent, user, sorrybox, i18n("Authentication failed") );
615
 
                        return false;
616
 
                case V_FAIL:
617
 
                        debug( " V_FAIL\n" );
618
 
                        return false;
619
 
                default:
620
 
                        logPanic( "Unknown V_xxx code %d from core\n", ret );
621
 
                }
622
 
        }
 
552
    char *msg;
 
553
    QString user;
 
554
 
 
555
    debug("handleFailVerify ...\n");
 
556
 
 
557
    if (showUser) {
 
558
        msg = gRecvStr();
 
559
        user = QString::fromLocal8Bit(msg);
 
560
        free(msg);
 
561
    }
 
562
 
 
563
    for (;;) {
 
564
        int ret = gRecvInt();
 
565
 
 
566
        // non-terminal status
 
567
        switch (ret) {
 
568
        /* case V_PUT_USER: cannot happen - we are in "classic" mode */
 
569
        /* case V_PRE_OK: cannot happen - not in ChTok dialog */
 
570
        /* case V_CHTOK: cannot happen - called by non-interactive verify */
 
571
        case V_CHTOK_AUTH:
 
572
            debug(" V_CHTOK_AUTH\n");
 
573
            {
 
574
                QStringList pgs(_pluginsLogin);
 
575
                pgs += _pluginsShutdown;
 
576
                foreach (const QString& pg, pgs)
 
577
                    if (pg == "classic" || pg == "modern") {
 
578
                        pgs = QStringList(pg);
 
579
                        goto gotit;
 
580
                    } else if (pg == "generic") {
 
581
                        pgs = QStringList("modern");
 
582
                        goto gotit;
 
583
                    }
 
584
                pgs = QStringList("classic");
 
585
              gotit:
 
586
                KGChTok chtok(parent, user, init(pgs), 0,
 
587
                              KGreeterPlugin::AuthChAuthTok,
 
588
                              KGreeterPlugin::Login);
 
589
                return chtok.exec();
 
590
            }
 
591
        case V_MSG_ERR:
 
592
            debug(" V_MSG_ERR\n");
 
593
            msg = gRecvStr();
 
594
            debug("  message %\"s\n", msg);
 
595
            vrfErrBox(parent, user, msg);
 
596
            free(msg);
 
597
            gSendInt(0);
 
598
            continue;
 
599
        case V_MSG_INFO_AUTH: // should not happen
 
600
        case V_MSG_INFO:
 
601
            debug(" V_MSG_INFO\n");
 
602
            msg = gRecvStr();
 
603
            debug("  message %\"s\n", msg);
 
604
            vrfInfoBox(parent, user, msg);
 
605
            free(msg);
 
606
            gSendInt(0);
 
607
            continue;
 
608
        }
 
609
 
 
610
        // terminal status
 
611
        switch (ret) {
 
612
        case V_OK:
 
613
            debug(" V_OK\n");
 
614
            return true;
 
615
        case V_AUTH:
 
616
            debug(" V_AUTH\n");
 
617
            vrfMsgBox(parent, user, sorrybox, i18n("Authentication failed"));
 
618
            return false;
 
619
        case V_FAIL:
 
620
            debug(" V_FAIL\n");
 
621
            return false;
 
622
        default:
 
623
            logPanic("Unknown V_xxx code %d from core\n", ret);
 
624
        }
 
625
    }
623
626
}
624
627
 
625
628
void // private
626
629
KGVerify::handleVerify()
627
630
{
628
 
        debug( "handleVerify ...\n" );
629
 
        QString user;
630
 
        char *msg;
631
 
        int ret, echo, ndelay;
632
 
        KGreeterPlugin::Function nfunc;
633
 
 
634
 
        ret = gRecvInt();
635
 
 
636
 
        // requests
637
 
        coreState = CorePrompting;
638
 
        switch (ret) {
639
 
        case V_GET_TEXT:
640
 
                debug( " V_GET_TEXT\n" );
641
 
                msg = gRecvStr();
642
 
                debug( "  prompt %\"s\n", msg );
643
 
                echo = gRecvInt();
644
 
                debug( "  echo = %d\n", echo );
645
 
                ndelay = gRecvInt();
646
 
                debug( "  ndelay = %d\n%s->textPrompt(...)\n", ndelay, pName.data() );
647
 
                greet->textPrompt( msg, echo, ndelay );
648
 
                free( msg );
649
 
                return;
650
 
        case V_GET_BINARY:
651
 
                debug( " V_GET_BINARY\n" );
652
 
                msg = gRecvArr( &ret );
653
 
                debug( "  %d bytes prompt\n", ret );
654
 
                ndelay = gRecvInt();
655
 
                debug( "  ndelay = %d\n%s->binaryPrompt(...)\n", ndelay, pName.data() );
656
 
                greet->binaryPrompt( msg, ndelay );
657
 
                free( msg );
658
 
                return;
659
 
        }
660
 
 
661
 
        // non-terminal status
662
 
        coreState = CoreBusy;
663
 
        switch (ret) {
664
 
        case V_PUT_USER:
665
 
                debug( " V_PUT_USER\n" );
666
 
                msg = gRecvStr();
667
 
                curUser = pamUser = QString::fromLocal8Bit( msg );
668
 
                // greet needs this to be able to return something useful from
669
 
                // getEntity(). but the backend is still unable to tell a domain ...
670
 
                debug( "  %s->setUser(%\"s)\n", pName.data(), qPrintable( user ) );
671
 
                greet->setUser( curUser );
672
 
                handler->verifySetUser( curUser );
673
 
                free( msg );
674
 
                return;
675
 
        case V_PRE_OK: // this is only for func == AuthChAuthTok
676
 
                debug( " V_PRE_OK\n" );
677
 
                // With the "classic" method, the wrong user simply cannot be
678
 
                // authenticated, even with the generic plugin. Other methods
679
 
                // could do so, but this applies only to ctx == ChangeTok, which
680
 
                // is not implemented yet.
681
 
                authTok = true;
682
 
                debug( "%s->succeeded()\n", pName.data() );
683
 
                greet->succeeded();
684
 
                return;
685
 
        case V_MSG_ERR:
686
 
                debug( " V_MSG_ERR\n" );
687
 
                timer.suspend();
688
 
                msg = gRecvStr();
689
 
                debug( "  %s->textMessage(%\"s, true)\n", pName.data(), msg );
690
 
                if (!greet->textMessage( msg, true )) { // XXX little point in filtering
691
 
                        debug( "  message passed\n" );
692
 
                        vrfErrBox( parent, pamUser, msg );
693
 
                } else
694
 
                        debug( "  message swallowed\n" );
695
 
                free( msg );
696
 
                gSendInt( 0 );
697
 
                timer.resume();
698
 
                return;
699
 
        case V_MSG_INFO_AUTH:
700
 
                debug( " V_MSG_INFO_AUTH\n" );
701
 
                timer.suspend();
702
 
                msg = gRecvStr();
703
 
                debug( "  %s->textMessage(%\"s, false)\n", pName.data(), msg );
704
 
                if (!greet->textMessage( msg, false )) {
705
 
                        debug( "  message passed\n" );
706
 
                        vrfInfoBox( parent, pamUser, msg );
707
 
                } else
708
 
                        debug( "  message swallowed\n" );
709
 
                free( msg );
710
 
                gSendInt( 0 );
711
 
                timer.resume();
712
 
                return;
713
 
        case V_MSG_INFO:
714
 
                debug( " V_MSG_INFO\n" );
715
 
                timer.suspend();
716
 
                msg = gRecvStr();
717
 
                debug( "  display %\"s\n", msg );
718
 
                vrfInfoBox( parent, pamUser, msg );
719
 
                free( msg );
720
 
                gSendInt( 0 );
721
 
                timer.resume();
722
 
                return;
723
 
        }
724
 
 
725
 
        // terminal status
726
 
        coreState = CoreIdle;
727
 
        running = false;
728
 
        sockNot->setEnabled( false );
729
 
        timer.stop();
730
 
 
731
 
        // These codes are not really terminal as far as the core is concerned,
732
 
        // but the branches as a whole are.
733
 
        if (ret == V_CHTOK_AUTH) {
734
 
                debug( " V_CHTOK_AUTH\n" );
735
 
                nfunc = KGreeterPlugin::AuthChAuthTok;
736
 
                user = curUser;
737
 
                goto dchtok;
738
 
        } else if (ret == V_CHTOK) {
739
 
                debug( " V_CHTOK\n" );
740
 
                nfunc = KGreeterPlugin::ChAuthTok;
741
 
                user.clear();
742
 
          dchtok:
743
 
                debug( "%s->succeeded()\n", pName.data() );
744
 
                greet->succeeded();
745
 
                KGChTok chtok( parent, user, pluginList, curPlugin, nfunc, KGreeterPlugin::Login );
746
 
                if (!chtok.exec())
747
 
                        goto retry;
748
 
                handler->verifyOk();
749
 
                return;
750
 
        }
751
 
 
752
 
        if (ret == V_OK) {
753
 
                debug( " V_OK\n" );
754
 
                if (!fixedEntity.isEmpty()) {
755
 
                        debug( "  %s->getEntity()\n", pName.data() );
756
 
                        QString ent = greet->getEntity();
757
 
                        debug( "  entity %\"s\n", qPrintable( ent ) );
758
 
                        if (ent != fixedEntity) {
759
 
                                debug( "%s->failed()\n", pName.data() );
760
 
                                greet->failed();
761
 
                                msgBox( sorrybox,
762
 
                                                i18n("Authenticated user (%1) does not match requested user (%2).\n",
763
 
                                                         ent, fixedEntity ) );
764
 
                                goto retry;
765
 
                        }
766
 
                }
767
 
                debug( "%s->succeeded()\n", pName.data() );
768
 
                greet->succeeded();
769
 
                handler->verifyOk();
770
 
                return;
771
 
        }
772
 
 
773
 
        debug( "%s->failed()\n", pName.data() );
774
 
        greet->failed();
775
 
 
776
 
        if (ret == V_AUTH) {
777
 
                debug( " V_AUTH\n" );
778
 
                failed = true;
779
 
                updateStatus();
780
 
                handler->verifyFailed();
781
 
                timer.start( 1500 + KRandom::random()/(RAND_MAX/1000) );
782
 
                return;
783
 
        }
784
 
        if (ret != V_FAIL)
785
 
                logPanic( "Unknown V_xxx code %d from core\n", ret );
786
 
        debug( " V_FAIL\n" );
 
631
    debug("handleVerify ...\n");
 
632
    QString user;
 
633
    char *msg;
 
634
    int ret, echo, ndelay;
 
635
    KGreeterPlugin::Function nfunc;
 
636
 
 
637
    ret = gRecvInt();
 
638
 
 
639
    // requests
 
640
    coreState = CorePrompting;
 
641
    switch (ret) {
 
642
    case V_GET_TEXT:
 
643
        debug(" V_GET_TEXT\n");
 
644
        msg = gRecvStr();
 
645
        debug("  prompt %\"s\n", msg);
 
646
        echo = gRecvInt();
 
647
        debug("  echo = %d\n", echo);
 
648
        ndelay = gRecvInt();
 
649
        debug("  ndelay = %d\n%s->textPrompt(...)\n", ndelay, pName.data());
 
650
        greet->textPrompt(msg, echo, ndelay);
 
651
        free(msg);
 
652
        return;
 
653
    case V_GET_BINARY:
 
654
        debug(" V_GET_BINARY\n");
 
655
        msg = gRecvArr(&ret);
 
656
        debug("  %d bytes prompt\n", ret);
 
657
        ndelay = gRecvInt();
 
658
        debug("  ndelay = %d\n%s->binaryPrompt(...)\n", ndelay, pName.data());
 
659
        greet->binaryPrompt(msg, ndelay);
 
660
        free(msg);
 
661
        return;
 
662
    }
 
663
 
 
664
    // non-terminal status
 
665
    coreState = CoreBusy;
 
666
    switch (ret) {
 
667
    case V_PUT_USER:
 
668
        debug(" V_PUT_USER\n");
 
669
        msg = gRecvStr();
 
670
        curUser = pamUser = QString::fromLocal8Bit(msg);
 
671
        // greet needs this to be able to return something useful from
 
672
        // getEntity(). but the backend is still unable to tell a domain ...
 
673
        debug("  %s->setUser(%\"s)\n", pName.data(), qPrintable(user));
 
674
        greet->setUser(curUser);
 
675
        handler->verifySetUser(curUser);
 
676
        free(msg);
 
677
        return;
 
678
    case V_PRE_OK: // this is only for func == AuthChAuthTok
 
679
        debug(" V_PRE_OK\n");
 
680
        // With the "classic" method, the wrong user simply cannot be
 
681
        // authenticated, even with the generic plugin. Other methods
 
682
        // could do so, but this applies only to ctx == ChangeTok, which
 
683
        // is not implemented yet.
 
684
        authTok = true;
 
685
        debug("%s->succeeded()\n", pName.data());
 
686
        greet->succeeded();
 
687
        return;
 
688
    case V_MSG_ERR:
 
689
        debug(" V_MSG_ERR\n");
 
690
        timer.suspend();
 
691
        msg = gRecvStr();
 
692
        debug("  %s->textMessage(%\"s, true)\n", pName.data(), msg);
 
693
        if (!greet->textMessage(msg, true)) { // XXX little point in filtering
 
694
            debug("  message passed\n");
 
695
            vrfErrBox(parent, pamUser, msg);
 
696
        } else {
 
697
            debug("  message swallowed\n");
 
698
        }
 
699
        free(msg);
 
700
        gSendInt(0);
 
701
        timer.resume();
 
702
        return;
 
703
    case V_MSG_INFO_AUTH:
 
704
        debug(" V_MSG_INFO_AUTH\n");
 
705
        timer.suspend();
 
706
        msg = gRecvStr();
 
707
        debug("  %s->textMessage(%\"s, false)\n", pName.data(), msg);
 
708
        if (!greet->textMessage(msg, false)) {
 
709
            debug("  message passed\n");
 
710
            vrfInfoBox(parent, pamUser, msg);
 
711
        } else {
 
712
            debug("  message swallowed\n");
 
713
        }
 
714
        free(msg);
 
715
        gSendInt(0);
 
716
        timer.resume();
 
717
        return;
 
718
    case V_MSG_INFO:
 
719
        debug(" V_MSG_INFO\n");
 
720
        timer.suspend();
 
721
        msg = gRecvStr();
 
722
        debug("  display %\"s\n", msg);
 
723
        vrfInfoBox(parent, pamUser, msg);
 
724
        free(msg);
 
725
        gSendInt(0);
 
726
        timer.resume();
 
727
        return;
 
728
    }
 
729
 
 
730
    // terminal status
 
731
    coreState = CoreIdle;
 
732
    running = false;
 
733
    sockNot->setEnabled(false);
 
734
    timer.stop();
 
735
 
 
736
    // These codes are not really terminal as far as the core is concerned,
 
737
    // but the branches as a whole are.
 
738
    if (ret == V_CHTOK_AUTH) {
 
739
        debug(" V_CHTOK_AUTH\n");
 
740
        nfunc = KGreeterPlugin::AuthChAuthTok;
 
741
        user = curUser;
 
742
        goto dchtok;
 
743
    } else if (ret == V_CHTOK) {
 
744
        debug(" V_CHTOK\n");
 
745
        nfunc = KGreeterPlugin::ChAuthTok;
 
746
        user.clear();
 
747
      dchtok:
 
748
        debug("%s->succeeded()\n", pName.data());
 
749
        greet->succeeded();
 
750
        KGChTok chtok(parent, user, pluginList, curPlugin, nfunc, KGreeterPlugin::Login);
 
751
        if (!chtok.exec())
 
752
            goto retry;
 
753
        handler->verifyOk();
 
754
        return;
 
755
    }
 
756
 
 
757
    if (ret == V_OK) {
 
758
        debug(" V_OK\n");
 
759
        if (!fixedEntity.isEmpty()) {
 
760
            debug("  %s->getEntity()\n", pName.data());
 
761
            QString ent = greet->getEntity();
 
762
            debug("  entity %\"s\n", qPrintable(ent));
 
763
            if (ent != fixedEntity) {
 
764
                debug("%s->failed()\n", pName.data());
 
765
                greet->failed();
 
766
                msgBox(sorrybox,
 
767
                       i18n("Authenticated user (%1) does not match requested user (%2).\n",
 
768
                            ent, fixedEntity));
 
769
                goto retry;
 
770
            }
 
771
        }
 
772
        debug("%s->succeeded()\n", pName.data());
 
773
        greet->succeeded();
 
774
        handler->verifyOk();
 
775
        return;
 
776
    }
 
777
 
 
778
    debug("%s->failed()\n", pName.data());
 
779
    greet->failed();
 
780
 
 
781
    if (ret == V_AUTH) {
 
782
        debug(" V_AUTH\n");
 
783
        failed = true;
 
784
        updateStatus();
 
785
        handler->verifyFailed();
 
786
        timer.start(1500 + KRandom::random() / (RAND_MAX / 1000));
 
787
        return;
 
788
    }
 
789
    if (ret != V_FAIL)
 
790
        logPanic("Unknown V_xxx code %d from core\n", ret);
 
791
    debug(" V_FAIL\n");
787
792
  retry:
788
 
        debug( "%s->revive()\n", pName.data() );
789
 
        greet->revive();
790
 
        sockNot->setEnabled( true );
791
 
        running = true;
792
 
        debug( "%s->start()\n", pName.data() );
793
 
        greet->start();
794
 
        slotActivity();
795
 
        talkerEdits();
796
 
}
797
 
 
798
 
void
799
 
KGVerify::gplugReturnText( const char *text, int tag )
800
 
{
801
 
        debug( "%s: gplugReturnText(%\"s, %d)\n", pName.data(),
802
 
               tag & V_IS_SECRET ? "<masked>" : text, tag );
803
 
        gSendStr( text );
804
 
        if (text) {
805
 
                gSendInt( tag );
806
 
                coreState = CoreBusy;
807
 
        } else
808
 
                coreState = CoreIdle;
809
 
}
810
 
 
811
 
void
812
 
KGVerify::gplugReturnBinary( const char *data )
813
 
{
814
 
        if (data) {
815
 
                unsigned const char *up = (unsigned const char *)data;
816
 
                int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24);
817
 
                debug( "%s: gplugReturnBinary(%d bytes)\n", pName.data(), len );
818
 
                gSendArr( len, data );
819
 
                coreState = CoreBusy;
820
 
        } else {
821
 
                debug( "%s: gplugReturnBinary(NULL)\n", pName.data() );
822
 
                gSendArr( 0, 0 );
823
 
                coreState = CoreIdle;
824
 
        }
825
 
}
826
 
 
827
 
void
828
 
KGVerify::gplugSetUser( const QString &user )
829
 
{
830
 
        debug( "%s: gplugSetUser(%\"s)\n", pName.data(), qPrintable( user ) );
831
 
        curUser = user;
832
 
        handler->verifySetUser( user );
 
793
    debug("%s->revive()\n", pName.data());
 
794
    greet->revive();
 
795
    sockNot->setEnabled(true);
 
796
    running = true;
 
797
    debug("%s->start()\n", pName.data());
 
798
    greet->start();
 
799
    slotActivity();
 
800
    talkerEdits();
 
801
}
 
802
 
 
803
void
 
804
KGVerify::gplugReturnText(const char *text, int tag)
 
805
{
 
806
    debug("%s: gplugReturnText(%\"s, %d)\n", pName.data(),
 
807
          tag & V_IS_SECRET ? "<masked>" : text, tag);
 
808
    gSendStr(text);
 
809
    if (text) {
 
810
        gSendInt(tag);
 
811
        coreState = CoreBusy;
 
812
    } else {
 
813
        coreState = CoreIdle;
 
814
    }
 
815
}
 
816
 
 
817
void
 
818
KGVerify::gplugReturnBinary(const char *data)
 
819
{
 
820
    if (data) {
 
821
        unsigned const char *up = (unsigned const char *)data;
 
822
        int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24);
 
823
        debug("%s: gplugReturnBinary(%d bytes)\n", pName.data(), len);
 
824
        gSendArr(len, data);
 
825
        coreState = CoreBusy;
 
826
    } else {
 
827
        debug("%s: gplugReturnBinary(NULL)\n", pName.data());
 
828
        gSendArr(0, 0);
 
829
        coreState = CoreIdle;
 
830
    }
 
831
}
 
832
 
 
833
void
 
834
KGVerify::gplugSetUser(const QString &user)
 
835
{
 
836
    debug("%s: gplugSetUser(%\"s)\n", pName.data(), qPrintable(user));
 
837
    curUser = user;
 
838
    handler->verifySetUser(user);
833
839
}
834
840
 
835
841
void
836
842
KGVerify::gplugStart()
837
843
{
838
 
        // XXX handle func != Authenticate
839
 
        if (coreState != CoreIdle)
840
 
                return;
841
 
        debug( "%s: gplugStart()\n", pName.data() );
842
 
        gSendInt( ctx == KGreeterPlugin::Shutdown ? G_VerifyRootOK : G_Verify );
843
 
        gSendStr( greetPlugins[pluginList[curPlugin]].info->method );
844
 
        coreState = CoreBusy;
 
844
    // XXX handle func != Authenticate
 
845
    if (coreState != CoreIdle)
 
846
        return;
 
847
    debug("%s: gplugStart()\n", pName.data());
 
848
    gSendInt(ctx == KGreeterPlugin::Shutdown ? G_VerifyRootOK : G_Verify);
 
849
    gSendStr(greetPlugins[pluginList[curPlugin]].info->method);
 
850
    coreState = CoreBusy;
845
851
}
846
852
 
847
853
void
848
854
KGVerify::gplugChanged()
849
855
{
850
 
        debug( "%s: gplugChanged()\n", pName.data() );
851
 
        if (parent->isActiveWindow())
852
 
                talkerEdits();
 
856
    debug("%s: gplugChanged()\n", pName.data());
 
857
    if (parent->isActiveWindow())
 
858
        talkerEdits();
853
859
}
854
860
 
855
861
void
856
862
KGVerify::gplugActivity()
857
863
{
858
 
        debug( "%s: gplugActivity()\n", pName.data() );
859
 
        slotActivity();
 
864
    debug("%s: gplugActivity()\n", pName.data());
 
865
    slotActivity();
860
866
}
861
867
 
862
868
void
863
 
KGVerify::gplugMsgBox( QMessageBox::Icon type, const QString &text )
 
869
KGVerify::gplugMsgBox(QMessageBox::Icon type, const QString &text)
864
870
{
865
 
        debug( "%s: gplugMsgBox(%d, %\"s)\n", pName.data(), type, qPrintable( text ) );
866
 
        msgBox( type, text );
 
871
    debug("%s: gplugMsgBox(%d, %\"s)\n", pName.data(), type, qPrintable(text));
 
872
    msgBox(type, text);
867
873
}
868
874
 
869
875
bool
870
 
KGVerify::eventFilter( QObject *o, QEvent *e )
 
876
KGVerify::eventFilter(QObject *o, QEvent *e)
871
877
{
872
 
        switch (e->type()) {
873
 
        case QEvent::KeyPress:
874
 
                if (timedLeft) {
875
 
                        QKeyEvent *ke = (QKeyEvent *)e;
876
 
                        if (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter) {
877
 
                                if (deadTicks <= 0) {
878
 
                                        timedLeft = 0;
879
 
                                        performAutoLogin();
880
 
                                }
881
 
                                return true;
882
 
                        }
883
 
                }
884
 
                /* fall through */
885
 
        case QEvent::KeyRelease:
886
 
                updateLockStatus();
887
 
                /* fall through */
888
 
        default:
889
 
                break;
890
 
        }
891
 
        return inherited::eventFilter( o, e );
 
878
    switch (e->type()) {
 
879
    case QEvent::KeyPress:
 
880
        if (timedLeft) {
 
881
            QKeyEvent *ke = (QKeyEvent *)e;
 
882
            if (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter) {
 
883
                if (deadTicks <= 0) {
 
884
                    timedLeft = 0;
 
885
                    performAutoLogin();
 
886
                }
 
887
                return true;
 
888
            }
 
889
        }
 
890
        /* fall through */
 
891
    case QEvent::KeyRelease:
 
892
        updateLockStatus();
 
893
        /* fall through */
 
894
    default:
 
895
        break;
 
896
    }
 
897
    return inherited::eventFilter(o, e);
892
898
}
893
899
 
894
900
void
895
901
KGVerify::updateLockStatus()
896
902
{
897
 
        unsigned int lmask;
898
 
        Window dummy1, dummy2;
899
 
        int dummy3, dummy4, dummy5, dummy6;
900
 
        XQueryPointer( QX11Info::display(), DefaultRootWindow( QX11Info::display() ),
901
 
                       &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6,
902
 
                       &lmask );
903
 
        capsLocked = lmask & LockMask;
904
 
        updateStatus();
 
903
    unsigned int lmask;
 
904
    Window dummy1, dummy2;
 
905
    int dummy3, dummy4, dummy5, dummy6;
 
906
    XQueryPointer(QX11Info::display(), DefaultRootWindow(QX11Info::display()),
 
907
                  &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6,
 
908
                  &lmask);
 
909
    capsLocked = lmask & LockMask;
 
910
    updateStatus();
905
911
}
906
912
 
907
913
void
908
 
KGVerify::msgBox( QMessageBox::Icon typ, const QString &msg )
 
914
KGVerify::msgBox(QMessageBox::Icon typ, const QString &msg)
909
915
{
910
 
        timer.suspend();
911
 
        KFMsgBox::box( parent, typ, msg );
912
 
        timer.resume();
 
916
    timer.suspend();
 
917
    KFMsgBox::box(parent, typ, msg);
 
918
    timer.resume();
913
919
}
914
920
 
915
921
 
916
922
QVariant // public static
917
 
KGVerify::getConf( void *, const char *key, const QVariant &dflt )
 
923
KGVerify::getConf(void *, const char *key, const QVariant &dflt)
918
924
{
919
 
        if (!qstrcmp( key, "EchoPasswd" ))
920
 
                return QVariant( _echoPasswd );
921
 
        else {
922
 
                QString fkey = QString::fromLatin1( key ) + '=';
923
 
                foreach (const QString& pgo, _pluginOptions)
924
 
                        if (pgo.startsWith( fkey ))
925
 
                                return pgo.mid( fkey.length() );
926
 
                return dflt;
927
 
        }
 
925
    if (!qstrcmp(key, "EchoPasswd")) {
 
926
        return QVariant(_echoPasswd);
 
927
    } else {
 
928
        QString fkey = QString::fromLatin1(key) + '=';
 
929
        foreach (const QString& pgo, _pluginOptions)
 
930
            if (pgo.startsWith(fkey))
 
931
                return pgo.mid(fkey.length());
 
932
        return dflt;
 
933
    }
928
934
}
929
935
 
930
936
QVector<GreeterPluginHandle> KGVerify::greetPlugins;
931
937
 
932
938
PluginList
933
 
KGVerify::init( const QStringList &plugins )
 
939
KGVerify::init(const QStringList &plugins)
934
940
{
935
 
        PluginList pluginList;
936
 
 
937
 
        foreach (const QString& pg, plugins) {
938
 
                GreeterPluginHandle plugin;
939
 
                KLibrary *lib = new KLibrary( pg[0] == '/' ? pg : "kgreet_" + pg );
940
 
                if (lib->fileName().isEmpty()) {
941
 
                        logError( "GreeterPlugin %s does not exist\n", qPrintable( pg ) );
942
 
                        delete lib;
943
 
                        continue;
944
 
                }
945
 
                uint i, np = greetPlugins.count();
946
 
                for (i = 0; i < np; i++)
947
 
                        if (greetPlugins[i].library->fileName() == lib->fileName()) {
948
 
                                delete lib;
949
 
                                goto next;
950
 
                        }
951
 
                if (!lib->load()) {
952
 
                        logError( "Cannot load GreeterPlugin %s (%s)\n",
953
 
                                  qPrintable( pg ), qPrintable( lib->fileName() ) );
954
 
                        delete lib;
955
 
                        continue;
956
 
                }
957
 
                plugin.library = lib;
958
 
                plugin.info = (KGreeterPluginInfo *)lib->resolveSymbol( "kgreeterplugin_info" );
959
 
                if (!plugin.info) {
960
 
                        logError( "GreeterPlugin %s (%s) is no valid greet widget plugin\n",
961
 
                                  qPrintable( pg ), qPrintable( lib->fileName() ) );
962
 
                        lib->unload();
963
 
                        delete lib;
964
 
                        continue;
965
 
                }
966
 
 
967
 
                if (!plugin.info->init( QString(), getConf, 0 )) {
968
 
                        logError( "GreeterPlugin %s (%s) refuses to serve\n",
969
 
                                  qPrintable( pg ), qPrintable( lib->fileName() ) );
970
 
                        lib->unload();
971
 
                        delete lib;
972
 
                        continue;
973
 
                }
974
 
                debug( "GreeterPlugin %s (%s) loaded\n", qPrintable( pg ), plugin.info->name );
975
 
                greetPlugins.append( plugin );
976
 
          next:
977
 
                pluginList.append( i );
978
 
        }
979
 
        return pluginList;
 
941
    PluginList pluginList;
 
942
 
 
943
    foreach (const QString& pg, plugins) {
 
944
        GreeterPluginHandle plugin;
 
945
        KLibrary *lib = new KLibrary(pg[0] == '/' ? pg : "kgreet_" + pg);
 
946
        if (lib->fileName().isEmpty()) {
 
947
            logError("GreeterPlugin %s does not exist\n", qPrintable(pg));
 
948
            delete lib;
 
949
            continue;
 
950
        }
 
951
        uint i, np = greetPlugins.count();
 
952
        for (i = 0; i < np; i++)
 
953
            if (greetPlugins[i].library->fileName() == lib->fileName()) {
 
954
                delete lib;
 
955
                goto next;
 
956
            }
 
957
        if (!lib->load()) {
 
958
            logError("Cannot load GreeterPlugin %s (%s)\n",
 
959
                     qPrintable(pg), qPrintable(lib->fileName()));
 
960
            delete lib;
 
961
            continue;
 
962
        }
 
963
        plugin.library = lib;
 
964
        plugin.info = (KGreeterPluginInfo *)lib->resolveSymbol("kgreeterplugin_info");
 
965
        if (!plugin.info) {
 
966
            logError("GreeterPlugin %s (%s) is no valid greet widget plugin\n",
 
967
                     qPrintable(pg), qPrintable(lib->fileName()));
 
968
            lib->unload();
 
969
            delete lib;
 
970
            continue;
 
971
        }
 
972
 
 
973
        if (!plugin.info->init(QString(), getConf, 0)) {
 
974
            logError("GreeterPlugin %s (%s) refuses to serve\n",
 
975
                     qPrintable(pg), qPrintable(lib->fileName()));
 
976
            lib->unload();
 
977
            delete lib;
 
978
            continue;
 
979
        }
 
980
        debug("GreeterPlugin %s (%s) loaded\n", qPrintable(pg), plugin.info->name);
 
981
        greetPlugins.append(plugin);
 
982
      next:
 
983
        pluginList.append(i);
 
984
    }
 
985
    return pluginList;
980
986
}
981
987
 
982
988
void
983
989
KGVerify::done()
984
990
{
985
 
        for (int i = 0; i < greetPlugins.count(); i++) {
986
 
                if (greetPlugins[i].info->done)
987
 
                        greetPlugins[i].info->done();
988
 
                greetPlugins[i].library->unload();
989
 
        }
 
991
    for (int i = 0; i < greetPlugins.count(); i++) {
 
992
        if (greetPlugins[i].info->done)
 
993
            greetPlugins[i].info->done();
 
994
        greetPlugins[i].library->unload();
 
995
    }
990
996
}
991
997
 
992
998
 
993
 
KGStdVerify::KGStdVerify( KGVerifyHandler *_handler, QWidget *_parent,
994
 
                          QWidget *_predecessor, const QString &_fixedUser,
995
 
                          const PluginList &_pluginList,
996
 
                          KGreeterPlugin::Function _func,
997
 
                          KGreeterPlugin::Context _ctx )
998
 
        : inherited( _handler, _parent, _predecessor, _fixedUser,
999
 
                     _pluginList, _func, _ctx )
1000
 
        , failedLabelState( 0 )
 
999
KGStdVerify::KGStdVerify(KGVerifyHandler *_handler, QWidget *_parent,
 
1000
                         QWidget *_predecessor, const QString &_fixedUser,
 
1001
                         const PluginList &_pluginList,
 
1002
                         KGreeterPlugin::Function _func,
 
1003
                         KGreeterPlugin::Context _ctx)
 
1004
    : inherited(_handler, _parent, _predecessor, _fixedUser,
 
1005
                _pluginList, _func, _ctx)
 
1006
    , failedLabelState(0)
1001
1007
{
1002
 
        grid = new QGridLayout;
1003
 
        grid->setAlignment( Qt::AlignCenter );
1004
 
 
1005
 
        failedLabel = new QLabel( parent );
1006
 
        failedLabel->setFont( *_failFont );
1007
 
        grid->addWidget( failedLabel, 1, 0, Qt::AlignCenter );
1008
 
 
1009
 
        updateLockStatus();
 
1008
    grid = new QGridLayout;
 
1009
    grid->setAlignment(Qt::AlignCenter);
 
1010
 
 
1011
    failedLabel = new QLabel(parent);
 
1012
    failedLabel->setFont(*_failFont);
 
1013
    grid->addWidget(failedLabel, 1, 0, Qt::AlignCenter);
 
1014
 
 
1015
    updateLockStatus();
1010
1016
}
1011
1017
 
1012
1018
KGStdVerify::~KGStdVerify()
1014
1020
}
1015
1021
 
1016
1022
bool
1017
 
KGStdVerify::gplugHasNode( const QString & )
 
1023
KGStdVerify::gplugHasNode(const QString &)
1018
1024
{
1019
 
        return false;
 
1025
    return false;
1020
1026
}
1021
1027
 
1022
1028
void // public
1023
 
KGStdVerify::selectPlugin( int id )
 
1029
KGStdVerify::selectPlugin(int id)
1024
1030
{
1025
 
        inherited::selectPlugin( id );
1026
 
        QWidget *w = greet->getWidgets().first();
1027
 
        grid->addWidget( w, 0, 0 );
1028
 
        w->show();
 
1031
    inherited::selectPlugin(id);
 
1032
    QWidget *w = greet->getWidgets().first();
 
1033
    grid->addWidget(w, 0, 0);
 
1034
    w->show();
1029
1035
}
1030
1036
 
1031
1037
void
1032
1038
KGStdVerify::updateStatus()
1033
1039
{
1034
 
        int nfls;
1035
 
 
1036
 
        if (!enabled)
1037
 
                nfls = 1;
1038
 
        else if (failed)
1039
 
                nfls = 2;
1040
 
        else if (timedLeft)
1041
 
                nfls = -timedLeft;
1042
 
        else if (!suspended && capsLocked)
1043
 
                nfls = 3;
1044
 
        else
1045
 
                nfls = 1;
1046
 
 
1047
 
        if (failedLabelState != nfls) {
1048
 
                failedLabelState = nfls;
1049
 
                QPalette p;
1050
 
                if (nfls < 0) {
1051
 
                        failedLabel->setText( i18np( "Automatic login in 1 second...",
1052
 
                                                     "Automatic login in %1 seconds...",
1053
 
                                                     timedLeft ) );
1054
 
                } else {
1055
 
                        switch (nfls) {
1056
 
                        default:
1057
 
                                failedLabel->clear();
1058
 
                                break;
1059
 
                        case 3:
1060
 
                                p.setBrush( QPalette::WindowText,
1061
 
                                        KColorScheme( QPalette::Active, KColorScheme::Window )
1062
 
                                                .foreground( KColorScheme::NegativeText ) );
1063
 
                                failedLabel->setText( i18n("Warning: Caps Lock is on") );
1064
 
                                break;
1065
 
                        case 2:
1066
 
                                failedLabel->setText( authTok ?
1067
 
                                                         i18n("Change failed") :
1068
 
                                                         fixedEntity.isEmpty() ?
1069
 
                                                            i18n("Login failed") :
1070
 
                                                            i18n("Authentication failed") );
1071
 
                                break;
1072
 
                        }
1073
 
                }
1074
 
                failedLabel->setPalette( p );
1075
 
        }
 
1040
    int nfls;
 
1041
 
 
1042
    if (!enabled)
 
1043
        nfls = 1;
 
1044
    else if (failed)
 
1045
        nfls = 2;
 
1046
    else if (timedLeft)
 
1047
        nfls = -timedLeft;
 
1048
    else if (!suspended && capsLocked)
 
1049
        nfls = 3;
 
1050
    else
 
1051
        nfls = 1;
 
1052
 
 
1053
    if (failedLabelState != nfls) {
 
1054
        failedLabelState = nfls;
 
1055
        QPalette p;
 
1056
        if (nfls < 0) {
 
1057
            failedLabel->setText(i18np("Automatic login in 1 second...",
 
1058
                                       "Automatic login in %1 seconds...",
 
1059
                                       timedLeft));
 
1060
        } else {
 
1061
            switch (nfls) {
 
1062
            default:
 
1063
                failedLabel->clear();
 
1064
                break;
 
1065
            case 3:
 
1066
                p.setBrush(QPalette::WindowText,
 
1067
                    KColorScheme(QPalette::Active, KColorScheme::Window)
 
1068
                        .foreground(KColorScheme::NegativeText));
 
1069
                failedLabel->setText(i18n("Warning: Caps Lock is on"));
 
1070
                break;
 
1071
            case 2:
 
1072
                failedLabel->setText(authTok ?
 
1073
                                         i18n("Change failed") :
 
1074
                                         fixedEntity.isEmpty() ?
 
1075
                                            i18n("Login failed") :
 
1076
                                            i18n("Authentication failed"));
 
1077
                break;
 
1078
            }
 
1079
        }
 
1080
        failedLabel->setPalette(p);
 
1081
    }
1076
1082
}
1077
1083
 
1078
 
KGThemedVerify::KGThemedVerify( KGVerifyHandler *_handler,
1079
 
                                KdmThemer *_themer,
1080
 
                                QWidget *_parent, QWidget *_predecessor,
1081
 
                                const QString &_fixedUser,
1082
 
                                const PluginList &_pluginList,
1083
 
                                KGreeterPlugin::Function _func,
1084
 
                                KGreeterPlugin::Context _ctx )
1085
 
        : inherited( _handler, _parent, _predecessor, _fixedUser,
1086
 
                     _pluginList, _func, _ctx )
1087
 
        , themer( _themer )
 
1084
KGThemedVerify::KGThemedVerify(KGVerifyHandler *_handler,
 
1085
                               KdmThemer *_themer,
 
1086
                               QWidget *_parent, QWidget *_predecessor,
 
1087
                               const QString &_fixedUser,
 
1088
                               const PluginList &_pluginList,
 
1089
                               KGreeterPlugin::Function _func,
 
1090
                               KGreeterPlugin::Context _ctx)
 
1091
    : inherited(_handler, _parent, _predecessor, _fixedUser,
 
1092
                _pluginList, _func, _ctx)
 
1093
    , themer(_themer)
1088
1094
{
1089
 
        updateLockStatus();
 
1095
    updateLockStatus();
1090
1096
}
1091
1097
 
1092
1098
KGThemedVerify::~KGThemedVerify()
1094
1100
}
1095
1101
 
1096
1102
bool
1097
 
KGThemedVerify::gplugHasNode( const QString &id )
 
1103
KGThemedVerify::gplugHasNode(const QString &id)
1098
1104
{
1099
 
        return themer->findNode( id ) != 0;
 
1105
    return themer->findNode(id) != 0;
1100
1106
}
1101
1107
 
1102
1108
void // public
1103
 
KGThemedVerify::selectPlugin( int id )
 
1109
KGThemedVerify::selectPlugin(int id)
1104
1110
{
1105
 
        if (curPlugin != -1)
1106
 
                themer->setTypeVisible( QString( "plugin-specific-" ).append( pluginName() ), false );
1107
 
        inherited::selectPlugin( id );
1108
 
        themer->setTypeVisible( QString( "plugin-specific-" ).append( pluginName() ), true );
1109
 
        QSet<QString> oldTypes = showTypes;
1110
 
        showTypes.clear();
1111
 
        foreach (QWidget *w, greet->getWidgets())
1112
 
                if (KdmItem *n = themer->findNode( w->objectName() )) {
1113
 
                        QString tn( QString( "plugin-" ).append( w->objectName() ) );
1114
 
                        themer->setTypeVisible( tn, true );
1115
 
                        showTypes.insert( tn );
1116
 
                        oldTypes.remove( tn );
1117
 
                        n->setWidget( w );
1118
 
                } else {
1119
 
                        msgBox( errorbox,
1120
 
                                i18n( "Theme not usable with authentication method '%1'.",
1121
 
                                      i18n( greetPlugins[pluginList[id]].info->name ) ) );
1122
 
                        break;
1123
 
                }
1124
 
        foreach (const QString& t, oldTypes)
1125
 
                themer->setTypeVisible( t, false );
 
1111
    if (curPlugin != -1)
 
1112
        themer->setTypeVisible(QString("plugin-specific-").append(pluginName()), false);
 
1113
    inherited::selectPlugin(id);
 
1114
    themer->setTypeVisible(QString("plugin-specific-").append(pluginName()), true);
 
1115
    QSet<QString> oldTypes = showTypes;
 
1116
    showTypes.clear();
 
1117
    foreach (QWidget *w, greet->getWidgets())
 
1118
        if (KdmItem *n = themer->findNode(w->objectName())) {
 
1119
            QString tn(QString("plugin-").append(w->objectName()));
 
1120
            themer->setTypeVisible(tn, true);
 
1121
            showTypes.insert(tn);
 
1122
            oldTypes.remove(tn);
 
1123
            n->setWidget(w);
 
1124
        } else {
 
1125
            msgBox(errorbox,
 
1126
                   i18n("Theme not usable with authentication method '%1'.",
 
1127
                        i18n(greetPlugins[pluginList[id]].info->name)));
 
1128
            break;
 
1129
        }
 
1130
    foreach (const QString &t, oldTypes)
 
1131
        themer->setTypeVisible(t, false);
1126
1132
}
1127
1133
 
1128
1134
void
1129
1135
KGThemedVerify::updateStatus()
1130
1136
{
1131
 
        handler->updateStatus( enabled && failed,
1132
 
                               enabled && !suspended && capsLocked,
1133
 
                               timedLeft );
 
1137
    handler->updateStatus(enabled && failed,
 
1138
                          enabled && !suspended && capsLocked,
 
1139
                          timedLeft);
1134
1140
}
1135
1141
 
1136
1142
 
1137
 
KGChTok::KGChTok( QWidget *_parent, const QString &user,
1138
 
                  const PluginList &pluginList, int curPlugin,
1139
 
                  KGreeterPlugin::Function func,
1140
 
                  KGreeterPlugin::Context ctx )
1141
 
        : inherited( _parent )
1142
 
        , verify( 0 )
 
1143
KGChTok::KGChTok(QWidget *_parent, const QString &user,
 
1144
                 const PluginList &pluginList, int curPlugin,
 
1145
                 KGreeterPlugin::Function func,
 
1146
                 KGreeterPlugin::Context ctx)
 
1147
    : inherited(_parent)
 
1148
    , verify(0)
1143
1149
{
1144
 
        QSizePolicy fp( QSizePolicy::Fixed, QSizePolicy::Fixed );
1145
 
        okButton = new KPushButton( KStandardGuiItem::ok(), this );
1146
 
        okButton->setSizePolicy( fp );
1147
 
        okButton->setDefault( true );
1148
 
        cancelButton = new KPushButton( KStandardGuiItem::cancel(), this );
1149
 
        cancelButton->setSizePolicy( fp );
1150
 
 
1151
 
        verify = new KGStdVerify( this, this, cancelButton, user, pluginList, func, ctx );
1152
 
        verify->selectPlugin( curPlugin );
1153
 
 
1154
 
        QVBoxLayout *box = new QVBoxLayout( this );
1155
 
 
1156
 
        box->addWidget( new QLabel( i18nc("@title:window",
1157
 
                                          "<qt><b>Changing authentication token</b></qt>"),
1158
 
                                    this ), 0, Qt::AlignHCenter|Qt::AlignTop );
1159
 
 
1160
 
        box->addLayout( verify->getLayout() );
1161
 
 
1162
 
        box->addWidget( new KSeparator( Qt::Horizontal, this ) );
1163
 
 
1164
 
        QHBoxLayout *hlay = new QHBoxLayout();
1165
 
        box->addLayout( hlay );
1166
 
        hlay->addStretch( 1 );
1167
 
        hlay->addWidget( okButton );
1168
 
        hlay->addStretch( 1 );
1169
 
        hlay->addWidget( cancelButton );
1170
 
        hlay->addStretch( 1 );
1171
 
 
1172
 
        connect( okButton, SIGNAL(clicked()), SLOT(accept()) );
1173
 
        connect( cancelButton, SIGNAL(clicked()), SLOT(reject()) );
1174
 
 
1175
 
        QTimer::singleShot( 0, verify, SLOT(start()) );
 
1150
    QSizePolicy fp(QSizePolicy::Fixed, QSizePolicy::Fixed);
 
1151
    okButton = new KPushButton(KStandardGuiItem::ok(), this);
 
1152
    okButton->setSizePolicy(fp);
 
1153
    okButton->setDefault(true);
 
1154
    cancelButton = new KPushButton(KStandardGuiItem::cancel(), this);
 
1155
    cancelButton->setSizePolicy(fp);
 
1156
 
 
1157
    verify = new KGStdVerify(this, this, cancelButton, user, pluginList, func, ctx);
 
1158
    verify->selectPlugin(curPlugin);
 
1159
 
 
1160
    QVBoxLayout *box = new QVBoxLayout(this);
 
1161
 
 
1162
    box->addWidget(new QLabel(i18nc("@title:window",
 
1163
                                    "<qt><b>Changing authentication token</b></qt>"),
 
1164
                              this), 0, Qt::AlignHCenter | Qt::AlignTop);
 
1165
 
 
1166
    box->addLayout(verify->getLayout());
 
1167
 
 
1168
    box->addWidget(new KSeparator(Qt::Horizontal, this));
 
1169
 
 
1170
    QHBoxLayout *hlay = new QHBoxLayout();
 
1171
    box->addLayout(hlay);
 
1172
    hlay->addStretch(1);
 
1173
    hlay->addWidget(okButton);
 
1174
    hlay->addStretch(1);
 
1175
    hlay->addWidget(cancelButton);
 
1176
    hlay->addStretch(1);
 
1177
 
 
1178
    connect(okButton, SIGNAL(clicked()), SLOT(accept()));
 
1179
    connect(cancelButton, SIGNAL(clicked()), SLOT(reject()));
 
1180
 
 
1181
    QTimer::singleShot(0, verify, SLOT(start()));
1176
1182
}
1177
1183
 
1178
1184
KGChTok::~KGChTok()
1179
1185
{
1180
 
        hide();
1181
 
        delete verify;
 
1186
    hide();
 
1187
    delete verify;
1182
1188
}
1183
1189
 
1184
1190
void
1185
1191
KGChTok::accept()
1186
1192
{
1187
 
        verify->accept();
 
1193
    verify->accept();
1188
1194
}
1189
1195
 
1190
1196
void
1191
 
KGChTok::verifyPluginChanged( int )
 
1197
KGChTok::verifyPluginChanged(int)
1192
1198
{
1193
 
        // cannot happen
 
1199
    // cannot happen
1194
1200
}
1195
1201
 
1196
1202
void
1197
1203
KGChTok::verifyOk()
1198
1204
{
1199
 
        inherited::accept();
 
1205
    inherited::accept();
1200
1206
}
1201
1207
 
1202
1208
void
1203
1209
KGChTok::verifyFailed()
1204
1210
{
1205
 
        okButton->setEnabled( false );
1206
 
        cancelButton->setEnabled( false );
 
1211
    okButton->setEnabled(false);
 
1212
    cancelButton->setEnabled(false);
1207
1213
}
1208
1214
 
1209
1215
void
1210
1216
KGChTok::verifyRetry()
1211
1217
{
1212
 
        okButton->setEnabled( true );
1213
 
        cancelButton->setEnabled( true );
 
1218
    okButton->setEnabled(true);
 
1219
    cancelButton->setEnabled(true);
1214
1220
}
1215
1221
 
1216
1222
void
1217
 
KGChTok::verifySetUser( const QString & )
 
1223
KGChTok::verifySetUser(const QString &)
1218
1224
{
1219
 
        // cannot happen
 
1225
    // cannot happen
1220
1226
}
1221
1227
 
1222
1228
 
1223
1229
////// helper class, nuke when qtimer supports suspend()/resume()
1224
1230
 
1225
1231
QXTimer::QXTimer()
1226
 
        : inherited( 0 )
1227
 
        , left( -1 )
 
1232
    : inherited(0)
 
1233
    , left(-1)
1228
1234
{
1229
 
        connect( &timer, SIGNAL(timeout()), SLOT(slotTimeout()) );
 
1235
    connect(&timer, SIGNAL(timeout()), SLOT(slotTimeout()));
1230
1236
}
1231
1237
 
1232
1238
void
1233
 
QXTimer::start( int msec )
 
1239
QXTimer::start(int msec)
1234
1240
{
1235
 
        left = msec;
1236
 
        timer.setSingleShot( true );
1237
 
        timer.start( left );
1238
 
        gettimeofday( &stv, 0 );
 
1241
    left = msec;
 
1242
    timer.setSingleShot(true);
 
1243
    timer.start(left);
 
1244
    gettimeofday(&stv, 0);
1239
1245
}
1240
1246
 
1241
1247
void
1242
1248
QXTimer::stop()
1243
1249
{
1244
 
        timer.stop();
1245
 
        left = -1;
 
1250
    timer.stop();
 
1251
    left = -1;
1246
1252
}
1247
1253
 
1248
1254
void
1249
1255
QXTimer::suspend()
1250
1256
{
1251
 
        if (timer.isActive()) {
1252
 
                timer.stop();
1253
 
                struct timeval tv;
1254
 
                gettimeofday( &tv, 0 );
1255
 
                left -= (tv.tv_sec - stv.tv_sec) * 1000 + (tv.tv_usec - stv.tv_usec) / 1000;
1256
 
                if (left < 0)
1257
 
                        left = 0;
1258
 
        }
 
1257
    if (timer.isActive()) {
 
1258
        timer.stop();
 
1259
        struct timeval tv;
 
1260
        gettimeofday(&tv, 0);
 
1261
        left -= (tv.tv_sec - stv.tv_sec) * 1000 + (tv.tv_usec - stv.tv_usec) / 1000;
 
1262
        if (left < 0)
 
1263
            left = 0;
 
1264
    }
1259
1265
}
1260
1266
 
1261
1267
void
1262
1268
QXTimer::resume()
1263
1269
{
1264
 
        if (left >= 0 && !timer.isActive()) {
1265
 
                timer.setSingleShot( true );
1266
 
                timer.start( left );
1267
 
                gettimeofday( &stv, 0 );
1268
 
        }
 
1270
    if (left >= 0 && !timer.isActive()) {
 
1271
        timer.setSingleShot(true);
 
1272
        timer.start(left);
 
1273
        gettimeofday(&stv, 0);
 
1274
    }
1269
1275
}
1270
1276
 
1271
1277
void
1272
1278
QXTimer::slotTimeout()
1273
1279
{
1274
 
        left = -1;
1275
 
        emit timeout();
 
1280
    left = -1;
 
1281
    emit timeout();
1276
1282
}
1277
1283
 
1278
1284