author | sandman <sandman> | 2002-10-14 00:59:28 (UTC) |
---|---|---|
committer | sandman <sandman> | 2002-10-14 00:59:28 (UTC) |
commit | 62c946c5a92ab11b5ad9495ff0bab158d38bce48 (patch) (side-by-side diff) | |
tree | 01375a50aace755e808eef3103d3c4395530b4f1 /core/opie-login/loginwindowimpl.cpp | |
parent | 72c07a1db3bad19fa227fc6fb482afe517d18095 (diff) | |
download | opie-62c946c5a92ab11b5ad9495ff0bab158d38bce48.zip opie-62c946c5a92ab11b5ad9495ff0bab158d38bce48.tar.gz opie-62c946c5a92ab11b5ad9495ff0bab158d38bce48.tar.bz2 |
- last login name is saved
- wait image should be displayed right now
- the qApp object is destroyed before the launcher is started -- this
should prevent some semaphore permission problems
- added a (very basic) crash handler
- added a simple "respawned too fast" detection in case of qt/e fb problems
- if opie-login is started with -a <user> or --autologin <user> it doesn't
prompt for a username/password - instead it loads qpe directly using the
specified user account
So even if you are not running multiuser, you should now start qpe with:
opie-login --autologin=root
Diffstat (limited to 'core/opie-login/loginwindowimpl.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/opie-login/loginwindowimpl.cpp | 270 |
1 files changed, 51 insertions, 219 deletions
diff --git a/core/opie-login/loginwindowimpl.cpp b/core/opie-login/loginwindowimpl.cpp index c59338f..3694513 100644 --- a/core/opie-login/loginwindowimpl.cpp +++ b/core/opie-login/loginwindowimpl.cpp @@ -1,345 +1,177 @@ #include <qapplication.h> #include <qpushbutton.h> #include <qlayout.h> #include <qframe.h> #include <qlineedit.h> #include <qtimer.h> #include <qcombobox.h> #include <qpixmap.h> #include <qlabel.h> #include <qpopupmenu.h> #include <qmessagebox.h> #include <qimage.h> #include <qpe/resource.h> #include <qpe/qcopenvelope_qws.h> +#include <qpe/config.h> #include <opie/odevice.h> #include <stdio.h> - -#include <pwd.h> -#include <grp.h> -#include <unistd.h> #include <stdlib.h> -#include <signal.h> - -#ifdef USEPAM -extern "C" { -#include <security/pam_appl.h> -} -#else -#include <crypt.h> -#include <shadow.h> -#endif #include "loginwindowimpl.h" +#include "loginapplication.h" #include "inputmethods.h" using namespace Opie; LoginWindowImpl::LoginWindowImpl ( ) : LoginWindow ( 0, "LOGIN-WINDOW", WStyle_Customize | WStyle_NoBorder | WDestructiveClose ) { QPopupMenu *pop = new QPopupMenu ( this ); pop-> insertItem ( tr( "Restart" ), this, SLOT( restart ( ))); pop-> insertItem ( tr( "Quit" ), this, SLOT( quit ( ))); m_menu-> setPopup ( pop ); QHBoxLayout *lay = new QHBoxLayout ( m_taskbar, 4, 4 ); m_input = new InputMethods ( m_taskbar ); lay-> addWidget ( m_input ); lay-> addStretch ( 10 ); setActiveWindow ( ); m_password-> setFocus ( ); - m_user-> insertStringList ( getAllUsers ( )); + m_user-> insertStringList ( lApp-> allUsers ( )); QTimer::singleShot ( 0, this, SLOT( showIM ( ))); QString opiedir = ::getenv ( "OPIEDIR" ); QPixmap bgpix ( opiedir + "/pics/launcher/opie-background.jpg" ); if ( !bgpix. isNull ( )) setBackgroundPixmap ( bgpix ); m_caption-> setText ( m_caption-> text ( ) + tr( "<center>%1 %2</center>" ). arg ( ODevice::inst ( )-> systemString ( )). arg ( ODevice::inst ( )-> systemVersionString ( ))); + + Config cfg ( "opie-login" ); + cfg. setGroup ( "General" ); + QString last = cfg. readEntry ( "LastLogin" ); + + if ( !last. isEmpty ( )) + m_user-> setEditText ( last ); } LoginWindowImpl::~LoginWindowImpl ( ) { } void LoginWindowImpl::keyPressEvent ( QKeyEvent *e ) { switch ( e-> key ( )) { case HardKey_Suspend: suspend ( ); break; case HardKey_Backlight: backlight ( ); break; default: e-> ignore ( ); break; } LoginWindow::keyPressEvent ( e ); } void LoginWindowImpl::toggleEchoMode ( bool t ) { m_password-> setEchoMode ( t ? QLineEdit::Normal : QLineEdit::Password ); } - -QStringList LoginWindowImpl::getAllUsers ( ) -{ - struct passwd *pwd; - QStringList sl; - - while (( pwd = ::getpwent ( ))) { - if (( pwd-> pw_uid == 0 ) || ( pwd-> pw_uid >= 500 && pwd-> pw_uid < 65534 )) - sl << QString ( pwd-> pw_name ); - } - - ::endpwent ( ); - - return sl; -} - void LoginWindowImpl::showIM ( ) { m_input-> showInputMethod ( ); } void LoginWindowImpl::restart ( ) { qApp-> quit ( ); } void LoginWindowImpl::quit ( ) { - qApp-> quit ( ); - ::kill ( ::getppid ( ), SIGUSR1 ); + lApp-> quitToConsole ( ); } void LoginWindowImpl::suspend ( ) { ODevice::inst ( )-> suspend ( ); QCopEnvelope e("QPE/System", "setBacklight(int)"); e << -3; // Force on } void LoginWindowImpl::backlight ( ) { QCopEnvelope e("QPE/System", "setBacklight(int)"); e << -2; // toggle } -#ifdef USEPAM - -static const char *_PAM_SERVICE = "xdm"; -static const char *PAM_password; - -typedef const struct pam_message pam_message_type; - -static int PAM_conv( int, pam_message_type **, struct pam_response **, void * ); - -static struct pam_conv PAM_conversation = { - &PAM_conv, - NULL -}; - -//---------------------------------------------------------------------------- - -static char *COPY_STRING( const char * s ) { - return (s) ? strdup(s) : (char *)NULL; -} - -#define GET_MEM if (reply) realloc(reply, size);\ - else reply = (struct pam_response *)malloc(size); \ - if (!reply) return PAM_CONV_ERR; \ - size += sizeof(struct pam_response) - - -static int PAM_conv( int num_msg, pam_message_type **msg, - struct pam_response **resp, void *) -{ - int count = 0, replies = 0; - struct pam_response *reply = NULL; - int size = sizeof(struct pam_response); - - for( count = 0; count < num_msg; count++ ) { - switch (msg[count]->msg_style) { - case PAM_PROMPT_ECHO_ON: - /* user name given to PAM already */ - return PAM_CONV_ERR; - - case PAM_PROMPT_ECHO_OFF: - /* wants password */ - GET_MEM; - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = COPY_STRING(PAM_password); - replies++; - /* PAM frees resp */ - break; - case PAM_TEXT_INFO: - break; - default: - /* unknown or PAM_ERROR_MSG */ - if (reply) free (reply); - return PAM_CONV_ERR; - } - } - if (reply) *resp = reply; - return PAM_SUCCESS; -} - - -static bool pwcheck_PAM( const char *user, const char *password ) -{ - bool pw_correct = false; - int pam_error; - int pam_return = 0; - pam_handle_t *pamh = 0; - PAM_password = password; - - pam_error = pam_start( _PAM_SERVICE, user, &PAM_conversation, &pamh ); - if( pam_error == PAM_SUCCESS ) { - pam_error = pam_authenticate( pamh, 0 ); - if( pam_error == PAM_SUCCESS ) { - //-- password correct - pw_correct = true; - pam_return = PAM_SUCCESS; - } else { - pam_return = pam_error; - } - } else { - // cerr << "PAM error: " << pam_strerror( pamh, pam_error ) << endl; - } - pam_end( pamh, pam_return ); - return pw_correct; -} - -#else - -//---------------------------------------------------------------------------- - -static bool pwcheck_Unix( const char *user, const char *pass ) -{ - char *encrypted, *correct; - struct passwd *pw; - - if ( !user || !pass ) - return false; - - pw = getpwnam ( user ); - - if ( !pw ) - return false; - - if (( strcmp ( pw-> pw_passwd, "x" ) == 0 ) || ( strcmp ( pw-> pw_passwd, "*" ) == 0 )) { - struct spwd *sp = getspnam ( pw-> pw_name ); - - if ( !sp ) - return false; - - correct = sp-> sp_pwdp; +class WaitLogo : public QLabel { +public: + WaitLogo ( ) : QLabel ( 0, "wait hack!", WStyle_Customize | WStyle_NoBorder | WStyle_Tool ) + { + QImage img = Resource::loadImage ( "launcher/new_wait" ); + QPixmap pix; + pix. convertFromImage ( img ); + setPixmap ( pix ); + setAlignment ( AlignCenter ); + move ( 0, 0 ); + resize ( qApp-> desktop ( )-> width ( ), qApp-> desktop ( )-> height ( )); + + m_visible = false; + show ( ); } - else - correct = pw-> pw_passwd; - - if ( correct == 0 || correct[0] == '\0' ) - return true; - encrypted = crypt ( pass, correct ); - return ( strcmp ( encrypted, correct ) == 0 ); -} - -#endif - - -bool LoginWindowImpl::changeIdentity ( const char *user ) -{ - const char *DEFAULT_LOGIN_PATH = "/bin:/usr/bin"; - const char *DEFAULT_ROOT_LOGIN_PATH = "/usr/sbin:/bin:/usr/bin:/sbin"; - - bool fail = false; - struct passwd *pw = getpwnam ( user ); - - fail |= ( pw == 0 ); - fail |= ( initgroups ( pw-> pw_name, pw-> pw_gid )); - endgrent ( ); - fail |= ( setgid ( pw-> pw_gid )); - fail |= ( setuid ( pw-> pw_uid )); - - fail |= ( chdir ( pw-> pw_dir ) && chdir ( "/" )); + virtual void showEvent ( QShowEvent *e ) + { + QLabel::showEvent ( e ); + m_visible = true; + } - fail |= ( setenv ( "HOME", pw-> pw_dir, 1 )); - fail |= ( setenv ( "SHELL", pw-> pw_shell, 1 )); - fail |= ( setenv ( "USER", pw-> pw_name, 1 )); - fail |= ( setenv ( "LOGNAME", pw-> pw_name, 1 )); - fail |= ( setenv ( "PATH", ( pw-> pw_uid ? DEFAULT_LOGIN_PATH : DEFAULT_ROOT_LOGIN_PATH ), 1 )); + virtual void paintEvent ( QPaintEvent *e ) + { + QLabel::paintEvent ( e ); + if ( m_visible ) + qApp-> quit ( ); + } - return !fail; -} +private: + bool m_visible; +}; void LoginWindowImpl::login ( ) { const char *user = ::strdup ( m_user-> currentText ( ). local8Bit ( )); const char *pass = ::strdup ( m_password-> text ( ). local8Bit ( )); - bool ok; if ( !user || !user [0] ) return; if ( !pass ) pass = ""; -#if defined( USEPAM ) - ok = pwcheck_PAM ( user, pass ); -#else - ok = pwcheck_Unix ( user, pass ); -#endif - - if ( ok ) { - if ( changeIdentity ( user )) { - // Draw a big wait icon, the image can be altered in later revisions - QWidget *d = QApplication::desktop ( ); - m_input-> hideInputMethod ( ); - - QImage img = Resource::loadImage( "launcher/new_wait" ); - QPixmap pix; - pix. convertFromImage ( img ); - QLabel *w = new QLabel ( 0, "wait hack!", WStyle_Customize | WStyle_NoBorder | WStyle_Tool ); - w-> setPixmap ( pix ); - w-> setAlignment ( AlignCenter ); - w-> showMaximized ( ); - qApp-> processEvents ( ); - - char *opie = ::getenv ( "OPIEDIR" ); - char *arg = new char [::strlen ( opie ) + 8 + 1]; - - ::strcpy ( arg, opie ); - ::strcat ( arg, "/bin/qpe" ); - - // start qpe via a login shell - ::execl ( "/bin/sh", "-sh", "-c", arg, 0 ); - - w-> hide ( ); - delete w; - - QMessageBox::critical ( this, tr( "Failure" ), tr( "Could not start OPIE\n(%1)." ). arg ( arg )); - delete [] arg; - - restart ( ); - } - else { - QMessageBox::critical ( this, tr( "Failure" ), tr( "Could not switch to new user identity" )); - restart ( ); - } + if ( lApp-> checkPassword ( user, pass )) { + Config cfg ( "opie-login" ); + cfg. setGroup ( "General" ); + cfg. writeEntry ( "LastLogin", user ); + cfg. write ( ); + + lApp-> setLoginAs ( user ); + + // Draw a big wait icon, the image can be altered in later revisions + m_input-> hideInputMethod ( ); + new WaitLogo ( ); + // WaitLogo::showEvent() calls qApp-> quit() } else { QMessageBox::warning ( this, tr( "Wrong password" ), tr( "The given password is incorrect." )); m_password-> clear ( ); } } |