summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--core/opie-login/loginwindow.ui6
-rw-r--r--core/opie-login/loginwindowimpl.cpp19
2 files changed, 25 insertions, 0 deletions
diff --git a/core/opie-login/loginwindow.ui b/core/opie-login/loginwindow.ui
index edd0819..5a35c8d 100644
--- a/core/opie-login/loginwindow.ui
+++ b/core/opie-login/loginwindow.ui
@@ -24,389 +24,395 @@
</property>
<property>
<name>layoutSpacing</name>
</property>
<vbox>
<property stdset="1">
<name>margin</name>
<number>0</number>
</property>
<property stdset="1">
<name>spacing</name>
<number>0</number>
</property>
<widget>
<class>QLayoutWidget</class>
<property stdset="1">
<name>name</name>
<cstring>Layout7</cstring>
</property>
<property>
<name>layoutMargin</name>
</property>
<property>
<name>layoutSpacing</name>
</property>
<vbox>
<property stdset="1">
<name>margin</name>
<number>4</number>
</property>
<property stdset="1">
<name>spacing</name>
<number>4</number>
</property>
<widget>
<class>QLabel</class>
<property stdset="1">
<name>name</name>
<cstring>m_caption</cstring>
</property>
<property stdset="1">
<name>sizePolicy</name>
<sizepolicy>
<hsizetype>5</hsizetype>
<vsizetype>5</vsizetype>
</sizepolicy>
</property>
<property stdset="1">
<name>font</name>
<font>
<family>helvetica</family>
<pointsize>18</pointsize>
<bold>1</bold>
<underline>1</underline>
</font>
</property>
<property stdset="1">
<name>autoMask</name>
<bool>true</bool>
</property>
<property stdset="1">
<name>backgroundOrigin</name>
<enum>ParentOrigin</enum>
</property>
<property stdset="1">
<name>margin</name>
<number>1</number>
</property>
<property stdset="1">
<name>text</name>
<string>&lt;center&gt;Welcome to OPIE&lt;/center&gt;</string>
</property>
</widget>
<widget>
<class>QLayoutWidget</class>
<property stdset="1">
<name>name</name>
<cstring>Layout6</cstring>
</property>
<property>
<name>layoutSpacing</name>
</property>
<grid>
<property stdset="1">
<name>margin</name>
<number>0</number>
</property>
<property stdset="1">
<name>spacing</name>
<number>4</number>
</property>
<widget row="0" column="1" >
<class>QComboBox</class>
<property stdset="1">
<name>name</name>
<cstring>m_user</cstring>
</property>
<property stdset="1">
<name>autoMask</name>
<bool>true</bool>
</property>
<property stdset="1">
<name>editable</name>
<bool>true</bool>
</property>
<property stdset="1">
<name>autoCompletion</name>
<bool>true</bool>
</property>
</widget>
<widget row="0" column="0" >
<class>QLabel</class>
<property stdset="1">
<name>name</name>
<cstring>TextLabel1</cstring>
</property>
<property stdset="1">
<name>autoMask</name>
<bool>true</bool>
</property>
<property stdset="1">
<name>backgroundOrigin</name>
<enum>ParentOrigin</enum>
</property>
<property stdset="1">
<name>text</name>
<string>User</string>
</property>
</widget>
<widget row="1" column="1" >
<class>QLayoutWidget</class>
<property stdset="1">
<name>name</name>
<cstring>Layout5</cstring>
</property>
<property>
<name>layoutSpacing</name>
</property>
<hbox>
<property stdset="1">
<name>margin</name>
<number>0</number>
</property>
<property stdset="1">
<name>spacing</name>
<number>4</number>
</property>
<widget>
<class>QLineEdit</class>
<property stdset="1">
<name>name</name>
<cstring>m_password</cstring>
</property>
<property stdset="1">
<name>autoMask</name>
<bool>true</bool>
</property>
<property stdset="1">
<name>echoMode</name>
<enum>Password</enum>
</property>
</widget>
<widget>
<class>QToolButton</class>
<property stdset="1">
<name>name</name>
<cstring>ToolButton3</cstring>
</property>
<property stdset="1">
<name>text</name>
<string></string>
</property>
<property stdset="1">
<name>pixmap</name>
<pixmap>image0</pixmap>
</property>
<property stdset="1">
<name>toggleButton</name>
<bool>true</bool>
</property>
<property stdset="1">
<name>toggleButton</name>
<bool>true</bool>
</property>
</widget>
<widget>
<class>QToolButton</class>
<property stdset="1">
<name>name</name>
<cstring>ToolButton1</cstring>
</property>
<property stdset="1">
<name>text</name>
<string></string>
</property>
<property stdset="1">
<name>pixmap</name>
<pixmap>image1</pixmap>
</property>
</widget>
</hbox>
</widget>
<widget row="1" column="0" >
<class>QLabel</class>
<property stdset="1">
<name>name</name>
<cstring>TextLabel2</cstring>
</property>
<property stdset="1">
<name>autoMask</name>
<bool>true</bool>
</property>
<property stdset="1">
<name>backgroundOrigin</name>
<enum>ParentOrigin</enum>
</property>
<property stdset="1">
<name>text</name>
<string>Password</string>
</property>
</widget>
</grid>
</widget>
<widget>
<class>Line</class>
<property stdset="1">
<name>name</name>
<cstring>Line1</cstring>
</property>
<property stdset="1">
<name>orientation</name>
<enum>Horizontal</enum>
</property>
</widget>
<widget>
<class>QLayoutWidget</class>
<property stdset="1">
<name>name</name>
<cstring>Layout3</cstring>
</property>
<property>
<name>layoutSpacing</name>
</property>
<hbox>
<property stdset="1">
<name>margin</name>
<number>0</number>
</property>
<property stdset="1">
<name>spacing</name>
<number>4</number>
</property>
<widget>
<class>QPushButton</class>
<property stdset="1">
<name>name</name>
<cstring>m_login</cstring>
</property>
<property stdset="1">
<name>autoMask</name>
<bool>true</bool>
</property>
<property stdset="1">
<name>text</name>
<string>Login</string>
</property>
</widget>
<widget>
<class>QPushButton</class>
<property stdset="1">
<name>name</name>
<cstring>m_suspend</cstring>
</property>
<property stdset="1">
<name>autoMask</name>
<bool>true</bool>
</property>
<property stdset="1">
<name>text</name>
<string>Suspend</string>
</property>
</widget>
<widget>
<class>QPushButton</class>
<property stdset="1">
<name>name</name>
<cstring>m_menu</cstring>
</property>
<property stdset="1">
<name>autoMask</name>
<bool>true</bool>
</property>
<property stdset="1">
<name>text</name>
<string>Menu</string>
</property>
</widget>
</hbox>
</widget>
<spacer>
<property>
<name>name</name>
<cstring>Spacer1</cstring>
</property>
<property stdset="1">
<name>orientation</name>
<enum>Vertical</enum>
</property>
<property stdset="1">
<name>sizeType</name>
<enum>Expanding</enum>
</property>
<property>
<name>sizeHint</name>
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</vbox>
</widget>
<widget>
<class>QFrame</class>
<property stdset="1">
<name>name</name>
<cstring>m_taskbar</cstring>
</property>
<property stdset="1">
<name>frameShape</name>
<enum>NoFrame</enum>
</property>
<property stdset="1">
<name>frameShadow</name>
<enum>Raised</enum>
</property>
<property stdset="1">
<name>margin</name>
<number>0</number>
</property>
</widget>
</vbox>
</widget>
<images>
<image>
<name>image0</name>
<data format="XPM.GZ" length="394">789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523234530022230543251d2e253d856405bffcbc54105b19c856360003b0141a808a2983b03284848a298304c108240e15033141045829580cac07ac4e590f5d0c22a4876caf32d45898797a48044caf32c22948e629c39d0457a78ce60f65b8f104ec50d6c366af1e865eb4b0aab5e602008bcd444d</data>
</image>
<image>
<name>image1</name>
<data format="XPM.GZ" length="341">789c558fcd0a02310c84ef7d8ad0b915c9bae84d7c04c5a3201e4275d1c32ab8eb41c477b73fa96e43a1f30d4d266d1ced771b728d194619af9efc451ee44ecfbe7f1d8eebb7b1ed92c259506b67c63279dade6fe7a81134e6a9224ac4ae2bc85565075004901c8820731069a648b490effc26eac4a25dcc195373c94231b87a8349fabf894b7a3d27a76af8cf01eb0e534757d70da1bf8a933f2bf30509e84b68</data>
</image>
</images>
<connections>
<connection>
<sender>ToolButton1</sender>
<signal>clicked()</signal>
<receiver>m_password</receiver>
<slot>clear()</slot>
</connection>
<connection>
<sender>ToolButton3</sender>
<signal>toggled(bool)</signal>
<receiver>LoginWindow</receiver>
<slot>toggleEchoMode(bool)</slot>
</connection>
<connection>
<sender>m_suspend</sender>
<signal>clicked()</signal>
<receiver>LoginWindow</receiver>
<slot>suspend()</slot>
</connection>
<connection>
<sender>m_password</sender>
<signal>returnPressed()</signal>
<receiver>m_login</receiver>
<slot>animateClick()</slot>
</connection>
<connection>
<sender>m_login</sender>
<signal>clicked()</signal>
<receiver>LoginWindow</receiver>
<slot>login()</slot>
</connection>
+ <connection>
+ <sender>m_user</sender>
+ <signal>activated(int)</signal>
+ <receiver>m_password</receiver>
+ <slot>setFocus()</slot>
+ </connection>
<slot access="public">login()</slot>
<slot access="public">suspend()</slot>
<slot access="public">toggleEchoMode(bool)</slot>
</connections>
</UI>
diff --git a/core/opie-login/loginwindowimpl.cpp b/core/opie-login/loginwindowimpl.cpp
index 63baaa6..c59338f 100644
--- a/core/opie-login/loginwindowimpl.cpp
+++ b/core/opie-login/loginwindowimpl.cpp
@@ -1,326 +1,345 @@
#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 <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 "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 ( ));
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 ( )));
}
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 );
}
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;
}
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 ( "/" ));
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 ));
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 )) {
+ // 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 ( );
}
}
else {
QMessageBox::warning ( this, tr( "Wrong password" ), tr( "The given password is incorrect." ));
m_password-> clear ( );
}
}