home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / kgreeterplugin.h < prev    next >
Encoding:
C/C++ Source or Header  |  2005-10-10  |  15.1 KB  |  402 lines

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