From 62c946c5a92ab11b5ad9495ff0bab158d38bce48 Mon Sep 17 00:00:00 2001 From: sandman Date: Mon, 14 Oct 2002 00:59:28 +0000 Subject: - 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 or --autologin 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 --- (limited to 'core/opie-login/loginwindowimpl.cpp') 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 @@ -13,27 +13,15 @@ #include #include +#include #include #include - -#include -#include -#include #include -#include - -#ifdef USEPAM -extern "C" { -#include -} -#else -#include -#include -#endif #include "loginwindowimpl.h" +#include "loginapplication.h" #include "inputmethods.h" using namespace Opie; @@ -54,7 +42,7 @@ LoginWindowImpl::LoginWindowImpl ( ) : LoginWindow ( 0, "LOGIN-WINDOW", WStyle_C setActiveWindow ( ); m_password-> setFocus ( ); - m_user-> insertStringList ( getAllUsers ( )); + m_user-> insertStringList ( lApp-> allUsers ( )); QTimer::singleShot ( 0, this, SLOT( showIM ( ))); @@ -65,6 +53,13 @@ LoginWindowImpl::LoginWindowImpl ( ) : LoginWindow ( 0, "LOGIN-WINDOW", WStyle_C setBackgroundPixmap ( bgpix ); m_caption-> setText ( m_caption-> text ( ) + tr( "
%1 %2
" ). 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 ( ) @@ -90,22 +85,6 @@ 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 ( ); @@ -118,8 +97,7 @@ void LoginWindowImpl::restart ( ) void LoginWindowImpl::quit ( ) { - qApp-> quit ( ); - ::kill ( ::getppid ( ), SIGUSR1 ); + lApp-> quitToConsole ( ); } void LoginWindowImpl::suspend ( ) @@ -136,207 +114,61 @@ void LoginWindowImpl::backlight ( ) 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." )); -- cgit v0.9.0.2