~ubuntu-branches/ubuntu/warty/kdebase/warty

« back to all changes in this revision

Viewing changes to kdm/kfrontend/kgreeterplugin.h

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-09-16 04:51:45 UTC
  • Revision ID: james.westby@ubuntu.com-20040916045145-9vr63kith3k1cpza
Tags: upstream-3.2.2
ImportĀ upstreamĀ versionĀ 3.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
    Authentication method specific conversation plugin for KDE's greeter widgets
 
4
 
 
5
    Copyright (C) 2003 Oswald Buddenhagen <ossi@kde.org>
 
6
    Copyright (C) 2003 Fabian Kaiser <xfk@softpro.de>
 
7
 
 
8
    This library is free software; you can redistribute it and/or
 
9
    modify it under the terms of the GNU Library General Public
 
10
    License as published by the Free Software Foundation; either
 
11
    version 2 of the License, or (at your option) any later version.
 
12
 
 
13
    This library is distributed in the hope that it will be useful,
 
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
    Library General Public License for more details.
 
17
 
 
18
    You should have received a copy of the GNU Library General Public License
 
19
    along with this library; see the file COPYING.LIB.  If not, write to
 
20
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
21
    Boston, MA 02111-1307, USA.
 
22
*/
 
23
 
 
24
#ifndef KGREETERPLUGIN_H
 
25
#define KGREETERPLUGIN_H
 
26
 
 
27
#include <qvariant.h>
 
28
 
 
29
class QWidget;
 
30
class QLayoutItem;
 
31
 
 
32
class KGreeterPluginHandler {
 
33
public:
 
34
    /* keep in sync with V_IS_* */
 
35
    enum { IsUser = 1, IsPassword = 2 };
 
36
    /**
 
37
     * Reply to textPrompt().
 
38
     * @param text text to return to core; null to abort auth cycle
 
39
     * @param tag zero or one of Is*
 
40
     */
 
41
    virtual void gplugReturnText( const char *text, int tag ) = 0;
 
42
    /**
 
43
     * Reply to binaryPrompt().
 
44
     * @param data data in pam_client format to return to the core;
 
45
     *  null to abort auth cycle
 
46
     */
 
47
    virtual void gplugReturnBinary( const char *data ) = 0;
 
48
    /**
 
49
     * Tell the greeter who is logging in.
 
50
     * Call this preferably before gplugStart, as otherwise the .dmrc
 
51
     * load will be delayed. Don't call at all if your plugin doesn't
 
52
     * have the Local flag set.
 
53
     * @param user the user logging in
 
54
     */
 
55
    virtual void gplugSetUser( const QString &user ) = 0;
 
56
    /**
 
57
     * Start processing.
 
58
     */
 
59
    virtual void gplugStart() = 0;
 
60
    /**
 
61
     * Plugins that expect user input from a different device than the mouse or
 
62
     * keyboard must call this when user activity is detected to prevent the
 
63
     * greeter from resetting/going away. Events should be compressed to no
 
64
     * more than ten per second; one every five seconds is actually enough.
 
65
     */
 
66
    virtual void gplugActivity() = 0;
 
67
};
 
68
 
 
69
/**
 
70
 * Abstract base class for conversation plugins ("talkers") to be used with
 
71
 * KDM, kdesktop_lock, etc.
 
72
 * The authentication method used by a particular instance of a plugin
 
73
 * may be configurable, but the instance must handle exactly one method,
 
74
 * i.e., info->method must be determined at the latest at init() time.
 
75
 */
 
76
class KGreeterPlugin {
 
77
public:
 
78
    KGreeterPlugin( KGreeterPluginHandler *h ) : handler( h ) {}
 
79
    virtual ~KGreeterPlugin() {}
 
80
 
 
81
    /**
 
82
     * Variations of the talker:
 
83
     * - Authenticate: authentication
 
84
     * - AuthChAuthTok: authentication and password change
 
85
     * - ChAuthTok: password change
 
86
     */
 
87
    enum Function { Authenticate, AuthChAuthTok, ChAuthTok };
 
88
    /**
 
89
     * Contexts the talker can be used in:
 
90
     * - Login: kdm login dialog
 
91
     * - Shutdown: kdm shutdown dialog
 
92
     * - Unlock: kdm unlock dialog (TODO)
 
93
     * - ChangeTok: kdm password change dialog (TODO)
 
94
     * - ExUnlock: kdesktop_lock unlock dialog
 
95
     * - ExChangeTok: kdepasswd password change dialog (TODO)
 
96
     *
 
97
     * The Ex* contexts exist within a running session; the talker must know
 
98
     * how to obtain the currently logged in user (+ domain/realm, etc.)
 
99
     * itself (i.e., fixedEntity will be null). The non-Ex variants will have
 
100
     * a fixedEntity passed in.
 
101
     */
 
102
    enum Context { Login, Shutdown, Unlock, ChangeTok,
 
103
                   ExUnlock, ExChangeTok };
 
104
 
 
105
    /**
 
106
     * Preload the talker with an (opaque to the greeter) entity.
 
107
     * Will be called only when not running.
 
108
     * @param entity the entity to preload the talker with. That
 
109
     *  will usually be something like "user" or "user@domain".
 
110
     * @param field the sub-widget (probably line edit) to put the cursor into
 
111
     */
 
112
    virtual void presetEntity( const QString &entity, int field ) = 0;
 
113
 
 
114
    /**
 
115
     * Obtain the actually logged in entity.
 
116
     * Will be called only after succeeded() was called.
 
117
     */
 
118
    virtual QString getEntity() const = 0;
 
119
 
 
120
    /**
 
121
     * "Push" a user into the talker. That can be a click into the user list
 
122
     * or successful authentication without the talker calling gplugSetUser.
 
123
     * Will be called only when running.
 
124
     * @param user the user to set. Note that this is a UNIX login, not a
 
125
     *  canonical entity
 
126
     */
 
127
    virtual void setUser( const QString &user ) = 0;
 
128
 
 
129
    /**
 
130
     * En-/disable any widgets contained in the talker.
 
131
     * Will be called only when not running.
 
132
     * @param on the state to set
 
133
     */
 
134
    virtual void setEnabled( bool on ) = 0;
 
135
 
 
136
    /**
 
137
     * Called when a message from the authentication backend arrives.
 
138
     * @param message the message received from the backend
 
139
     * @param error if true, @p message is an error message, otherwise it's
 
140
     *  an informational message
 
141
     * @return true means that the talker already handled the message, false
 
142
     *  that the greeter should display it in a message box
 
143
     *
 
144
     * FIXME: Filtering a message usually means that the backend issued a
 
145
     * prompt and obtains the authentication data itself. However, in that
 
146
     * state the backend is unresponsive, e.g., no shutdown is possible.
 
147
     * The frontend could send the backend a signal, but the "escape path"
 
148
     * within the backend is unclear (PAM won't like simply longjmp()ing
 
149
     * out of it).
 
150
     */
 
151
    virtual bool textMessage( const char *message, bool error ) = 0;
 
152
 
 
153
    /**
 
154
     * Prompt the user for data. Reply by calling handler->gplugReturnText().
 
155
     * @param propmt the prompt to display. It may be null, in which case
 
156
     *  "Username"/"Password" should be shown and the replies should be tagged
 
157
     *  with the respective Is* flag.
 
158
     * @param echo if true, a normal input widget can be used, otherwise one that
 
159
     *  visually obscures the user's input.
 
160
     * @param nonBlocking if true, report whatever is already available,
 
161
     *  otherwise wait for user input.
 
162
     */
 
163
    virtual void textPrompt( const char *prompt, bool echo, bool nonBlocking ) = 0;
 
164
 
 
165
    /**
 
166
     * Request binary authentication data from the talker. Reply by calling
 
167
     * handler->gplugReturnBinary().
 
168
     * @param prompt prompt in pam_client format
 
169
     * @param nonBlocking if true, report whatever is already available,
 
170
     *  otherwise wait for user input.
 
171
     * @return always true for now
 
172
     *
 
173
     * TODO:
 
174
     * @return if true, the prompt was handled by the talker, otherwise the
 
175
     *  handler has to use libpam_client to obtain the authentication data.
 
176
     *  In that state the talker still can abort the data fetch by
 
177
     *  gplugReturn()ing a null array. When the data was obtained, another
 
178
     *  binaryPrompt with a null prompt will be issued.
 
179
     */
 
180
    virtual bool binaryPrompt( const char *prompt, bool nonBlocking ) = 0;
 
181
 
 
182
    /**
 
183
     * This can either
 
184
     *  - Start a processing cycle. Will be called only when not running.
 
185
     *  - Restart authTok cycle - will be called while running and implies
 
186
     *    revive(). PAM is a bit too clever, so we need this.
 
187
     * In any case the talker is running afterwards.
 
188
     */
 
189
    virtual void start() = 0;
 
190
 
 
191
    /**
 
192
     * Request to suspend the auth. Make sure that a second talker of any
 
193
     * type will be able to operate while this one is suspended (no busy
 
194
     * device nodes, etc.).
 
195
     * Will be called only if running within Login context. (Actually it
 
196
     * won't be called at all, but be prepared.)
 
197
     */
 
198
    virtual void suspend() = 0;
 
199
 
 
200
    /**
 
201
     * Request to resume the auth from the point it was suspended at.
 
202
     * Will be called only when suspended.
 
203
     */
 
204
    virtual void resume() = 0;
 
205
 
 
206
    /**
 
207
     * The "login" button was pressed in the greeter.
 
208
     * This might call gplugReturn* or gplugStart.
 
209
     * Will be called only when running.
 
210
     */
 
211
    virtual void next() = 0;
 
212
 
 
213
    /**
 
214
     * Abort auth cycle. Note that this should _not_ clear out already
 
215
     * entered auth tokens if they are still on the screen.
 
216
     * Will be called only when running and stops it.
 
217
     */
 
218
    virtual void abort() = 0;
 
219
 
 
220
    /**
 
221
     * Indicate successful end of the current phase.
 
222
     * This is more or less a request to disable editable widgets
 
223
     * responsible for the that phase.
 
224
     * There will be no further attempt to enter that phase until the
 
225
     * widget is destroyed.
 
226
     * Will be called only when running and stops it.
 
227
     */
 
228
    virtual void succeeded() = 0;
 
229
 
 
230
    /**
 
231
     * Indicate unsuccessful end of the current phase.
 
232
     * This is mostly a request to disable all editable widgets.
 
233
     * The widget will be treated as dead until revive() is called.
 
234
     * Will be called only when running and stops it.
 
235
     */
 
236
    virtual void failed() = 0;
 
237
 
 
238
    /**
 
239
     * Prepare retrying the previously failed phase.
 
240
     * This is mostly a request to re-enable all editable widgets failed()
 
241
     * disabled previously, clear the probably incorrect authentication tokens
 
242
     * and to set the input focus appropriately.
 
243
     * Will be called only after failed() (possibly with clear() in between).
 
244
     */
 
245
    virtual void revive() = 0;
 
246
 
 
247
    /**
 
248
     * Clear any edit widgets, particularily anything set by setUser.
 
249
     * Will be called only when not running.
 
250
     */
 
251
    virtual void clear() = 0;
 
252
 
 
253
    /**
 
254
     * Obtain the QLayoutItem containg the widget(s) to actually handle the
 
255
     * conversation. See QLayout and QWidgetItem for possible implementations.
 
256
     */
 
257
    QLayoutItem *getLayoutItem() const { return layoutItem; }
 
258
 
 
259
protected:
 
260
    KGreeterPluginHandler *handler;
 
261
    QLayoutItem *layoutItem;
 
262
};
 
263
 
 
264
struct kgreeterplugin_info {
 
265
    /**
 
266
     * Human readable name of this plugin (should be a little more
 
267
     * informative than just the libary name). Must be I18N_NOOP()ed.
 
268
     */
 
269
    const char *name;
 
270
 
 
271
    /**
 
272
     * The authentication method to use - the meaning is up to the backend,
 
273
     * but will usually be related to the PAM service.
 
274
     */
 
275
    const char *method;
 
276
 
 
277
    /**
 
278
     * Capabilities.
 
279
     */
 
280
    enum {
 
281
        /**
 
282
         * All users exist on the local system permanently (will be listed
 
283
         * by getpwent()); no domain/realm needs to be set interactively.
 
284
         * Effectively means that setUser/gplugSetUser can be used and a
 
285
         * userlist can be shown at all.
 
286
         */
 
287
        Local = 1
 
288
    };
 
289
    /*
 
290
     * Capability flags.
 
291
     */
 
292
    int flags;
 
293
    
 
294
    /**
 
295
     * Call after loading the plugin.
 
296
     *
 
297
     * @param method if non-empty and the plugin is unable to handle that
 
298
     *  method, return false. If the plugin has a constant method defined
 
299
     *  above, it can ignore this parameter.
 
300
     * @param getConf can be used to obtain configuration items from the
 
301
     *  greeter; you have to pass it the @p ctx pointer.
 
302
     *   The only predefined key (in KDM) is "EchoMode", which is an int
 
303
     *   (in fact, KPasswordEdit::EchoModes).
 
304
     *   Other keys are obtained from the PluginOptions option; see kdmrc
 
305
     *   for details.
 
306
     *   If the key is unknown, dflt is returned.
 
307
     * @param ctx context pointer for @p getConf
 
308
     * @return if false, unload the plugin again (don't call done() first)
 
309
     */
 
310
    bool (*init)( const QString &method,
 
311
                  QVariant (*getConf)( void *ctx, const char *key, const QVariant &dflt ),
 
312
                  void *ctx );
 
313
    /**
 
314
     * Call before unloading the plugin.
 
315
     * This pointer can be null.
 
316
     */
 
317
    void (*done)( void );
 
318
 
 
319
    /**
 
320
     * Factory method to create an instance of the plugin.
 
321
     * Note that multiple instances can exist at one time, but only
 
322
     * one of them is active at any moment (the others would be suspended
 
323
     * or not running at all).
 
324
     * @param handler the object offering the necessary callbacks
 
325
     * @param parent parent widget
 
326
     * @param predecessor the focus widget before the conversation widget
 
327
     * @param fixedEntity see below
 
328
     * @param func see below
 
329
     * @param ctx see below
 
330
     * @return an instance of this conversation plugin
 
331
     *
 
332
     * Valid combinations of Function and Context:
 
333
     * - Authenticate:Login - init
 
334
     * - Authenticate:Shutdown - init, for now "root" is passed as fixedEntitiy
 
335
     *  and it is not supposed to be displayed. Plugins with Local not set
 
336
     *  might have to conjure something up to make getEntity() return a
 
337
     *  canonical entitiy. FIXME: don't restrict shutdown to root.
 
338
     * - AuthChAuthTok:Login, AuthChAuthTok:Shutdown - cont/cont,
 
339
     *  only relevant for classic method (as it is relevant only for password-
 
340
     *  less logins, which always use classic). The login should not be shown -
 
341
     *  it is known to the user already; the backend won't ask for it, either.
 
342
     * - ChAuthTok:Login & ChAuthTok:Shutdown - cont
 
343
     * - Authenticate:Unlock & Authenticate:ExUnlock - init,
 
344
     *   AuthChAuthTok:ChangeTok & AuthChAuthTok:ExChangeTok - init/cont,
 
345
     *  display fixedEntity as labels. The backend does not ask for the UNIX
 
346
     *  login, as it already knows it - but it will ask for all components of
 
347
     *  the entity if it is no UNIX login.
 
348
     *
 
349
     * "init" means that the plugin is supposed to call gplugStart, "cont"
 
350
     * that the backend is already in a cycle of the method the plugin was
 
351
     * initialized with.
 
352
     */
 
353
    KGreeterPlugin *(*create)( KGreeterPluginHandler *handler,
 
354
                               QWidget *parent, QWidget *predecessor,
 
355
                               const QString &fixedEntity,
 
356
                               KGreeterPlugin::Function func,
 
357
                               KGreeterPlugin::Context ctx );
 
358
};
 
359
 
 
360
#endif