From dac5c073c3e04ceb6900aeb72e53cf6d7350c3c9 Mon Sep 17 00:00:00 2001 From: sandman Date: Sat, 27 Jul 2002 22:43:37 +0000 Subject: Initial checkin of the new opie-login Just replace $OPIEDIR/bin/qpe with $OPIEDIR/bin/opie-login in /etc/init.d/opie --- diff --git a/core/opie-login/loginwindow.ui b/core/opie-login/loginwindow.ui new file mode 100644 index 0000000..86d5469 --- a/dev/null +++ b/core/opie-login/loginwindow.ui @@ -0,0 +1,396 @@ + +LoginWindow + + QWidget + + name + LoginWindow + + + geometry + + 0 + 0 + 472 + 341 + + + + caption + Login + + + layoutMargin + + + layoutSpacing + + + + margin + 0 + + + spacing + 0 + + + QLayoutWidget + + name + Layout7 + + + layoutMargin + + + + margin + 4 + + + spacing + 6 + + + QLabel + + name + m_caption + + + sizePolicy + + 5 + 5 + + + + autoMask + true + + + backgroundOrigin + ParentOrigin + + + text + <center><h1>Welcome to OPIE</h1></center> + + + + QLayoutWidget + + name + Layout6 + + + layoutSpacing + + + + margin + 0 + + + spacing + 4 + + + QComboBox + + name + m_user + + + autoMask + true + + + editable + true + + + autoCompletion + true + + + + QLabel + + name + TextLabel1 + + + autoMask + true + + + backgroundOrigin + ParentOrigin + + + text + User + + + + QLayoutWidget + + name + Layout5 + + + layoutSpacing + + + + margin + 0 + + + spacing + 4 + + + QLineEdit + + name + m_password + + + autoMask + true + + + echoMode + Password + + + + QToolButton + + name + ToolButton3 + + + text + + + + pixmap + image0 + + + toggleButton + true + + + toggleButton + true + + + + QToolButton + + name + ToolButton1 + + + text + + + + pixmap + image1 + + + + + + QLabel + + name + TextLabel2 + + + autoMask + true + + + backgroundOrigin + ParentOrigin + + + text + Password + + + + + + Line + + name + Line1 + + + orientation + Horizontal + + + + QLayoutWidget + + name + Layout3 + + + layoutSpacing + + + + margin + 0 + + + spacing + 4 + + + QPushButton + + name + m_login + + + autoMask + true + + + text + Login + + + + QPushButton + + name + m_suspend + + + autoMask + true + + + text + Suspend + + + + QPushButton + + name + m_menu + + + autoMask + true + + + text + Menu + + + + + + + name + Spacer1 + + + orientation + Vertical + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + + + QFrame + + name + m_taskbar + + + frameShape + NoFrame + + + frameShadow + Raised + + + margin + 0 + + + + + + + image0 + 789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523234530022230543251d2e253d856405bffcbc54105b19c856360003b0141a808a2983b03284848a298304c108240e15033141045829580cac07ac4e590f5d0c22a4876caf32d45898797a48044caf32c22948e629c39d0457a78ce60f65b8f104ec50d6c366af1e865eb4b0aab5e602008bcd444d + + + image1 + 789c558fcd0a02310c84ef7d8ad0b915c9bae84d7c04c5a3201e4275d1c32ab8eb41c477b73fa96e43a1f30d4d266d1ced771b728d194619af9efc451ee44ecfbe7f1d8eebb7b1ed92c259506b67c63279dade6fe7a81134e6a9224ac4ae2bc85565075004901c8820731069a648b490effc26eac4a25dcc195373c94231b87a8349fabf894b7a3d27a76af8cf01eb0e534757d70da1bf8a933f2bf30509e84b68 + + + + + ToolButton1 + clicked() + m_password + clear() + + + ToolButton3 + toggled(bool) + LoginWindow + toggleEchoMode(bool) + + + m_suspend + clicked() + LoginWindow + suspend() + + + m_password + returnPressed() + m_login + animateClick() + + + m_login + clicked() + LoginWindow + login() + + login() + suspend() + toggleEchoMode(bool) + + diff --git a/core/opie-login/loginwindowimpl.cpp b/core/opie-login/loginwindowimpl.cpp new file mode 100644 index 0000000..3265b46 --- a/dev/null +++ b/core/opie-login/loginwindowimpl.cpp @@ -0,0 +1,323 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include +#include +#include + +#ifdef USEPAM +extern "C" { +#include +} +#else +#include +#include +#endif + +#include "loginwindowimpl.h" +#include "inputmethods.h" + +LoginWindowImpl::LoginWindowImpl ( ) : LoginWindow ( 0, "LOGIN-WINDOW", WStyle_Customize | WStyle_NoBorder | WDestructiveClose ) +{ + QPopupMenu *pop = new QPopupMenu ( this ); + pop-> insertItem ( tr( "Restart" ), this, SLOT( restart ( ))); + 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 ( )); + + 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( "

%1 %2

" ). arg ( ODevice::inst ( )-> systemString ( )). arg ( ODevice::inst ( )-> systemVersionString ( ))); +} + +LoginWindowImpl::~LoginWindowImpl ( ) +{ +} + +void LoginWindowImpl::keyPressEvent ( QKeyEvent *e ) +{ + switch ( e-> key ( )) { + case Key_F34: suspend ( ); + break; + case Key_F35: 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::suspend ( ) +{ + system ( "apm -s" ); + usleep ( 1 * 1000 * 1000 ); + { + 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; + } + 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 ); + printf ( "1 %d\n", fail ); + fail |= ( initgroups ( pw-> pw_name, pw-> pw_gid )); + endgrent ( ); + printf ( "2 %d\n", fail ); + fail |= ( setgid ( pw-> pw_gid )); + printf ( "3 %d\n", fail ); + fail |= ( setuid ( pw-> pw_uid )); + + printf ( "4 %d\n", fail ); + fail |= ( chdir ( pw-> pw_dir ) && chdir ( "/" )); + + printf ( "5 %d\n", fail ); + fail |= ( setenv ( "HOME", pw-> pw_dir, 1 )); + printf ( "6 %d\n", fail ); + fail |= ( setenv ( "SHELL", pw-> pw_shell, 1 )); + printf ( "7 %d\n", fail ); + fail |= ( setenv ( "USER", pw-> pw_name, 1 )); + printf ( "8 %d\n", fail ); + fail |= ( setenv ( "LOGNAME", pw-> pw_name, 1 )); + printf ( "9 %d\n", fail ); + fail |= ( setenv ( "PATH", ( pw-> pw_uid ? DEFAULT_LOGIN_PATH : DEFAULT_ROOT_LOGIN_PATH ), 1 )); + printf ( "10 %d\n", fail ); + + return !fail; +} + +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 )) { + QString opie = getenv ( "OPIEDIR" ); + opie += "/bin/qpe"; + + execl ( opie. latin1 ( ), "qpe", 0 ); + + QMessageBox::critical ( this, tr( "Failure" ), tr( "Could not start OPIE." )); + restart ( ); + } + else { + QMessageBox::critical ( this, tr( "Failure" ), tr( "Could not switch to new user identity" )); + restart ( ); + } + } + else { + QMessageBox::warning ( this, tr( "Wrong password" ), tr( "The given password is incorrect." )); + m_password-> clear ( ); + } +} diff --git a/core/opie-login/loginwindowimpl.h b/core/opie-login/loginwindowimpl.h new file mode 100644 index 0000000..16c42e6 --- a/dev/null +++ b/core/opie-login/loginwindowimpl.h @@ -0,0 +1,33 @@ +#ifndef __OPIE_LOGINWINDOW_IMPL_H__ +#define __OPIE_LOGINWINDOW_IMPL_H__ + +#include "loginwindow.h" + +class InputMethods; + +class LoginWindowImpl : public LoginWindow { + Q_OBJECT + +public: + LoginWindowImpl ( ); + virtual ~LoginWindowImpl ( ); + +protected slots: + void restart ( ); + void showIM ( ); + void suspend ( ); + void backlight ( ); + void login ( ); + void toggleEchoMode ( bool ); + +protected: + virtual void keyPressEvent ( QKeyEvent *e ); + + QStringList getAllUsers ( ); + bool changeIdentity ( const char *user ); + +private: + InputMethods *m_input; +}; + +#endif diff --git a/core/opie-login/main.cpp b/core/opie-login/main.cpp new file mode 100644 index 0000000..9d52b75 --- a/dev/null +++ b/core/opie-login/main.cpp @@ -0,0 +1,178 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include "loginwindowimpl.h" +#include "calibrate.h" + +int login_main ( int argc, char **argv ); + + +int main ( int argc, char **argv ) +{ + if ( geteuid ( ) != 0 ) { + fprintf ( stderr, "%s can only be executed by root. (or chmod +s)", argv [0] ); + return 1; + } + +// struct rlimit rl; +// getrlimit ( RLIMIT_NOFILE, &rl ); + +// for ( unsigned int i = 0; i < rl. rlim_cur; i++ ) +// close ( i ); + + setpgid ( 0, 0 ); + setsid ( ); + + openlog ( "opie-login", LOG_CONS, LOG_AUTHPRIV ); + + while ( true ) { + pid_t child = fork ( ); + + if ( child < 0 ) { + syslog ( LOG_ERR, "Could not fork process" ); + break; + + } + else if ( child > 0 ) { + int status = 0; + + while ( waitpid ( child, &status, 0 ) < 0 ) { } + } + else { + exit ( login_main ( argc, argv )); + } + } + closelog ( ); +} + + +class ModelKeyFilter : public QObject, public QWSServer::KeyboardFilter +{ +public: + ModelKeyFilter ( ) : QObject ( 0, "MODEL_KEY_FILTER" ) + { + bool doinst = false; + + m_model = ODevice::inst ( )-> model ( ); + m_power_timer = 0; + + switch ( m_model ) { + case OMODEL_iPAQ_H31xx: + case OMODEL_iPAQ_H36xx: + case OMODEL_iPAQ_H37xx: + case OMODEL_iPAQ_H38xx: doinst = true; + break; + default : break; + } + if ( doinst ) + QWSServer::setKeyboardFilter ( this ); + } + + virtual bool filter ( int /*unicode*/, int keycode, int modifiers, bool isPress, bool autoRepeat ) + { + bool kill = false; + + // Rotate cursor keys 180° + switch ( m_model ) { + case OMODEL_iPAQ_H31xx: + case OMODEL_iPAQ_H38xx: { + int newkeycode = keycode; + + switch ( keycode ) { + case Key_Left : newkeycode = Key_Right; break; + case Key_Right: newkeycode = Key_Left; break; + case Key_Up : newkeycode = Key_Down; break; + case Key_Down : newkeycode = Key_Up; break; + } + if ( newkeycode != keycode ) { + QWSServer::sendKeyEvent ( -1, newkeycode, modifiers, isPress, autoRepeat ); + kill = true; + } + break; + } + default: break; + } + + // map Power Button short/long press to F34/F35 + switch ( m_model ) { + case OMODEL_iPAQ_H31xx: + case OMODEL_iPAQ_H36xx: + case OMODEL_iPAQ_H37xx: + case OMODEL_iPAQ_H38xx: { + if ( keycode == Key_SysReq ) { + if ( isPress ) { + m_power_timer = startTimer ( 500 ); + } + else if ( m_power_timer ) { + killTimer ( m_power_timer ); + m_power_timer = 0; + QWSServer::sendKeyEvent ( -1, Key_F34, 0, true, false ); + QWSServer::sendKeyEvent ( -1, Key_F34, 0, false, false ); + } + kill = true; + } + break; + } + default: break; + } + return kill; + } + + virtual void timerEvent ( QTimerEvent * ) + { + killTimer ( m_power_timer ); + m_power_timer = 0; + QWSServer::sendKeyEvent ( -1, Key_F35, 0, true, false ); + QWSServer::sendKeyEvent ( -1, Key_F35, 0, false, false ); + } + +private: + OModel m_model; + int m_power_timer; +}; + + + + +int login_main ( int argc, char **argv ) +{ + QWSServer::setDesktopBackground( QImage() ); + QPEApplication app ( argc, argv, QApplication::GuiServer ); + + (void) new ModelKeyFilter ( ); + + { + QCopEnvelope e("QPE/System", "setBacklight(int)" ); + e << -3; // Forced on + } + +#if defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX) + if ( !QFile::exists ( "/etc/pointercal" )) { + // Make sure calibration widget starts on top. + Calibrate *cal = new Calibrate; + cal-> exec ( ); + delete cal; + } +#endif + + LoginWindowImpl *lw = new LoginWindowImpl ( ); + app. setMainWidget ( lw ); + lw-> setGeometry ( 0, 0, app. desktop ( )-> width ( ), app. desktop ( )-> height ( )); + lw-> show ( ); + + return app. exec ( ); +} + diff --git a/core/opie-login/opie-login.pro b/core/opie-login/opie-login.pro new file mode 100644 index 0000000..35c1ed0 --- a/dev/null +++ b/core/opie-login/opie-login.pro @@ -0,0 +1,25 @@ +TEMPLATE = app +CONFIG = qt warn_on debug usepam + +HEADERS = loginwindowimpl.h \ + ../launcher/inputmethods.h \ + ../apps/calibrate/calibrate.h + +SOURCES = loginwindowimpl.cpp \ + ../launcher/inputmethods.cpp \ + ../apps/calibrate/calibrate.cpp \ + main.cpp + +INTERFACES = loginwindow.ui + +INCLUDEPATH += $(OPIEDIR)/include ../launcher ../apps/calibrate +DEPENDPATH += $(OPIEDIR)/include ../launcher ../apps/calibrate + +LIBS += -lqpe -lopie + +usepam:LIBS += -lpam +usepam:DEFINES += USEPAM + +DESTDIR = $(OPIEDIR)/bin +TARGET = opie-login + -- cgit v0.9.0.2