From 944adb8bf2741a16cf627d19e08f51c08920ad89 Mon Sep 17 00:00:00 2001 From: zecke Date: Fri, 09 Jul 2004 21:36:37 +0000 Subject: Add setting a root password if none is set to opie-login If you directly start Opie-Taskbar or use AutoLogin you will not be presented by a set root password gui --- (limited to 'core/opie-login') diff --git a/core/opie-login/.cvsignore b/core/opie-login/.cvsignore index 0c3cc62..b80bdc4 100644 --- a/core/opie-login/.cvsignore +++ b/core/opie-login/.cvsignore @@ -2,6 +2,8 @@ Makefile* loginwindow.cpp loginwindow.h +passworddialog.h +passworddialog.cpp moc_* .moc .obj diff --git a/core/opie-login/loginwindowimpl.cpp b/core/opie-login/loginwindowimpl.cpp index 32f98f3..73c2cbe 100644 --- a/core/opie-login/loginwindowimpl.cpp +++ b/core/opie-login/loginwindowimpl.cpp @@ -47,6 +47,7 @@ #include #include +#include "passworddialogimpl.h" #include "loginwindowimpl.h" #include "loginapplication.h" #include "inputmethods.h" @@ -90,7 +91,7 @@ LoginWindowImpl::LoginWindowImpl ( ) : LoginWindow ( 0, "LOGIN-WINDOW", WStyle_C TextLabel2-> setBackgroundPixmap ( bgpix); } - m_caption-> setText ( tr("
Welcome to OPIE %1
& %2 %3
"). arg(QPE_VERSION). arg ( ODevice::inst ( )-> systemString ( )). arg ( ODevice::inst ( )-> systemVersionString ( ))); +// m_caption-> setText ( tr("
Welcome to OPIE %1
& %2 %3
"). arg(QPE_VERSION). arg ( ODevice::inst ( )-> systemString ( )). arg ( ODevice::inst ( )-> systemVersionString ( ))); Config cfg ( "opie-login" ); cfg. setGroup ( "General" ); @@ -100,6 +101,11 @@ LoginWindowImpl::LoginWindowImpl ( ) : LoginWindow ( 0, "LOGIN-WINDOW", WStyle_C m_user-> setEditText ( last ); calcMaxWindowRect ( ); + + if ( PasswordDialogImpl::needDialog() ) + QTimer::singleShot(10, this, SLOT(showPasswordDialog()) ); + + } LoginWindowImpl::~LoginWindowImpl ( ) @@ -248,3 +254,9 @@ void LoginWindowImpl::login ( ) m_password-> clear ( ); } } + +void LoginWindowImpl::showPasswordDialog() { + PasswordDialogImpl dia( this ); + dia.showMaximized(); + dia.exec(); +} diff --git a/core/opie-login/loginwindowimpl.h b/core/opie-login/loginwindowimpl.h index df8dbbb..1de212c 100644 --- a/core/opie-login/loginwindowimpl.h +++ b/core/opie-login/loginwindowimpl.h @@ -34,10 +34,10 @@ class InputMethods; class LoginWindowImpl : public LoginWindow { Q_OBJECT - + public: LoginWindowImpl ( ); - virtual ~LoginWindowImpl ( ); + virtual ~LoginWindowImpl ( ); protected slots: void restart ( ); @@ -49,6 +49,7 @@ protected slots: void toggleEchoMode ( bool ); void calcMaxWindowRect ( ); void receive ( const QCString &, const QByteArray & ); + void showPasswordDialog(); protected: virtual void keyPressEvent ( QKeyEvent *e ); diff --git a/core/opie-login/opie-login.pro b/core/opie-login/opie-login.pro index 63d4481..175d0b6 100644 --- a/core/opie-login/opie-login.pro +++ b/core/opie-login/opie-login.pro @@ -1,18 +1,20 @@ TEMPLATE = app CONFIG = qt warn_on usepam -HEADERS = loginwindowimpl.h \ +HEADERS = loginwindowimpl.h \ loginapplication.h \ + passworddialogimpl.h \ ../launcher/inputmethods.h \ ../apps/calibrate/calibrate.h -SOURCES = loginwindowimpl.cpp \ +SOURCES = loginwindowimpl.cpp \ loginapplication.cpp \ + passworddialogimpl.cpp \ ../launcher/inputmethods.cpp \ ../apps/calibrate/calibrate.cpp \ main.cpp -INTERFACES = loginwindow.ui +INTERFACES = loginwindow.ui passworddialog.ui INCLUDEPATH += $(OPIEDIR)/include ../launcher ../apps/calibrate DEPENDPATH += $(OPIEDIR)/include ../launcher ../apps/calibrate diff --git a/core/opie-login/passworddialog.ui b/core/opie-login/passworddialog.ui new file mode 100644 index 0000000..f2b2c88 --- a/dev/null +++ b/core/opie-login/passworddialog.ui @@ -0,0 +1,225 @@ + +PasswordDialog + + QDialog + + name + PasswordDialog + + + geometry + + 0 + 0 + 625 + 277 + + + + caption + Set Password + Caption of the password dialog + + + layoutMargin + + + layoutSpacing + + + + margin + 4 + + + spacing + 4 + + + QLabel + + name + m_header + + + text + <qt><h2>Please set a password for the Superuser.</h2></qt> + + + + QLayoutWidget + + name + Layout5 + + + + margin + 0 + + + spacing + 6 + + + QLineEdit + + name + m_pass + + + echoMode + Password + + + + QLabel + + name + m_passLabel + + + text + <b>Password:</b> + + + buddy + m_pass + + + + QToolButton + + name + ToolButton3 + + + text + + + + pixmap + image0 + + + toggleButton + true + + + toggleButton + true + + + + QToolButton + + name + ToolButton1_2 + + + text + + + + pixmap + image1 + + + + QLineEdit + + name + m_confirm + + + echoMode + Password + + + + QToolButton + + name + ToolButton1 + + + text + + + + pixmap + image1 + + + + QLabel + + name + m_confirmLbl + + + text + <b>Confirm:</b> + + + + + + + name + Spacer2 + + + orientation + Vertical + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + + + + image0 + 789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523234530022230543251d2e253d856405bffcbc54105b19c856360003b0141a808a2983b03284848a298304c108240e15033141045829580cac07ac4e590f5d0c22a4876caf32d45898797a48044caf32c22948e629c39d0457a78ce60f65b8f104ec50d6c366af1e865eb4b0aab5e602008bcd444d + + + image1 + 789c558fcd0a02310c84ef7d8ad0b915c9bae84d7c04c5a3201e4275d1c32ab8eb41c477b73fa96e43a1f30d4d266d1ced771b728d194619af9efc451ee44ecfbe7f1d8eebb7b1ed92c259506b67c63279dade6fe7a81134e6a9224ac4ae2bc85565075004901c8820731069a648b490effc26eac4a25dcc195373c94231b87a8349fabf894b7a3d27a76af8cf01eb0e534757d70da1bf8a933f2bf30509e84b68 + + + + + ToolButton3 + toggled(bool) + PasswordDialog + slotToggleEcho(bool) + + + ToolButton1 + clicked() + m_pass + clear() + + + ToolButton1_2 + clicked() + m_confirm + clear() + + slotToggleEcho(bool) + + + m_pass + m_confirm + + diff --git a/core/opie-login/passworddialogimpl.cpp b/core/opie-login/passworddialogimpl.cpp new file mode 100644 index 0000000..aeb7516 --- a/dev/null +++ b/core/opie-login/passworddialogimpl.cpp @@ -0,0 +1,232 @@ +/* +               =. This file is part of the OPIE Project +             .=l. Copyright (c) 2004 Holger Hans Peter Freyther +           .>+-= + _;:,     .>    :=|. This file is free software; you can +.> <`_,   >  .   <= redistribute it and/or modify it under +:`=1 )Y*s>-.--   : the terms of the GNU General Public +.="- .-=="i,     .._ License as published by the Free Software + - .   .-<_>     .<> Foundation; either version 2 of the License, +     ._= =}       : or (at your option) any later version. +    .%`+i>       _;_. +    .i_,=:_.      -`: PARTICULAR PURPOSE. See the GNU General +..}^=.=       =       ; Public License for more details. +++=   -.     .`     .: + :     =  ...= . :.=- You should have received a copy of the GNU + -.   .:....=;==+<; General Public License along with this file; +  -_. . .   )=.  = see the file COPYING. If not, write to the +    --        :-=` Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +#include "passworddialogimpl.h" + + +// This function is taken from 'busybox'. +static int i64c(int i) { + if (i <= 0) + return ('.'); + if (i == 1) + return ('/'); + if (i >= 2 && i < 12) + return ('0' - 2 + i); + if (i >= 12 && i < 38) + return ('A' - 12 + i); + if (i >= 38 && i < 63) + return ('a' - 38 + i); + return ('z'); +} + +// This function is taken from 'busybox'. +static char *crypt_make_salt() { + time_t now; + static unsigned long x; + static char result[3]; + + ::time(&now); + x += now + getpid() + clock(); + result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077); + result[1] = i64c(((x >> 12) ^ x) & 077); + result[2] = '\0'; + return result; +} + +/* + * Modal dialog to force root password. It is quite hard as it only leave + * when a password is set. + * Also it prevalidates the password... + */ +PasswordDialogImpl::PasswordDialogImpl( QWidget* parent ) + : PasswordDialog( parent, 0, true ), m_isSet( PasswordDialogImpl::needDialog() ) { +} + +PasswordDialogImpl::~PasswordDialogImpl() { + /* qt does the stuff for us */ +} + +void PasswordDialogImpl::done(int res) { + m_isSet = true; + + /* + * The user hit 'Ok' see if we can safe the file + * if not an error will be raised and m_isSet altered. + * On cancel we will see if it is now ok... + */ + if ( res == Accepted ) + writePassword(); + else if(PasswordDialogImpl::needDialog() ) { + switch( QMessageBox::warning(this,tr("Trying to leave without password set") , + tr("No password was set. This could lead to you not beeing" + "able to remotely connect to your machine." + "Do you want to continue not setting a password?" ), + QMessageBox::Ok, QMessageBox::Cancel ) ) { + case QMessageBox::Cancel: + m_isSet = false; + break; + case QMessageBox::Ok: + default: + break; + } + + } + + if(m_isSet) + PasswordDialog::done( res ); +} + +/* + * Lets see if we can write either shadow + * + */ +/** + * CRYPT the password and then tries to write it either to the shadow password + * or to the plain /etc/passwd + */ +void PasswordDialogImpl::writePassword() { + /* + * Check if both texts are the same + */ + if ( m_pass->text() != m_confirm->text() ) + return error( tr("Passwords don't match"), + tr("The two passwords don't match. Please try again.") ); + + + /* + * Now crypt the password so we can write it later + */ + char* password = ::crypt( m_pass->text().latin1(), crypt_make_salt() ); + + if ( !password ) + return error( tr("Password not legal" ), + tr("The entered password is not a valid password." + "Please try entering a valid password." ) ); + + /* rewind and rewrite the password file */ + ::setpwent(); + + FILE* file = ::fopen( "/etc/passwd.new", "w" ); + struct passwd* pass; + while ( (pass = ::getpwent()) != 0l ) { + /* no shadow password support */ + if ( pass->pw_uid == 0 ) + pass->pw_passwd = password; + + ::putpwent( pass, file ); + } + + ::fclose( file ); + ::endpwent(); + ::unlink("/etc/passwd"); + ::rename("/etc/passwd.new","/etc/passwd" ); + + /* should be done now */ +#ifdef OPIE_LOGIN_SHADOW_PW + #error "Can't write Shadow Passwords fixme" +#endif +} + +/** + * Raise an error. Delete input and set the focus after showing + * the error to the user + */ +void PasswordDialogImpl::error( const QString& caption, const QString& text ) { + m_isSet = false; + QMessageBox::critical(this,caption, text, + QMessageBox::Ok, QMessageBox::NoButton ); + + m_pass->setText(""); + m_pass->setFocus(); + + m_confirm->setText(""); +} + +void PasswordDialogImpl::slotToggleEcho( bool b ) { + m_pass-> setEchoMode( b ? QLineEdit::Normal : QLineEdit::Password ); + m_confirm->setEchoMode( b ? QLineEdit::Normal : QLineEdit::Password ); +} + +///////////////////////// +/// static functions +/// + +/** + * Ask whether or not we need to show the dialog. It returns true if + * no root password is set so that the user will be able to set one. + */ +bool PasswordDialogImpl::needDialog() { + /* + * This can cope with no password and shadow passwords + * Let us go through the user database until we find 'root' and then + * see if it is 'shadow' and see if shadow is empty or see if the password is empty + */ + bool need = false; + struct passwd *pwd; + ::setpwent(); + + while((pwd = ::getpwent() ) ) { + /* found root */ + if( pwd->pw_uid == 0 ) { + QString str = QString::fromLatin1(pwd->pw_passwd ); + + /* + * If str is really empty it is passwordless anyway... + * else it is shadow based + */ + if(str.isEmpty() ) + need = true; + else if ( str == '*' || str == 'x' ) +#ifdef OPIE_LOGIN_SHADOW_PW + need = QString::fromLatin1( ::getspnam( pwd->pw_name )->sp_pwdp ).isEmpty(); +#else + ; +#endif + break; + } + } + ::endpwent(); + + return need; +} diff --git a/core/opie-login/passworddialogimpl.h b/core/opie-login/passworddialogimpl.h new file mode 100644 index 0000000..f8953dd --- a/dev/null +++ b/core/opie-login/passworddialogimpl.h @@ -0,0 +1,65 @@ +/* +               =. This file is part of the OPIE Project +             .=l. Copyright (c) 2004 Holger Hans Peter Freyther +           .>+-= + _;:,     .>    :=|. This file is free software; you can +.> <`_,   >  .   <= redistribute it and/or modify it under +:`=1 )Y*s>-.--   : the terms of the GNU General Public +.="- .-=="i,     .._ License as published by the Free Software + - .   .-<_>     .<> Foundation; either version 2 of the License, +     ._= =}       : or (at your option) any later version. +    .%`+i>       _;_. +    .i_,=:_.      -`: PARTICULAR PURPOSE. See the GNU General +..}^=.=       =       ; Public License for more details. +++=   -.     .`     .: + :     =  ...= . :.=- You should have received a copy of the GNU + -.   .:....=;==+<; General Public License along with this file; +  -_. . .   )=.  = see the file COPYING. If not, write to the +    --        :-=` Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + + +#ifndef OPIE_LOGIN_PASSWORDIMPL_DIALOG_H +#define OPIE_LOGIN_PASSWORDIMPL_DIALOG_H + +#include "passworddialog.h" + + +class QLineEdit; +/** + * Small Dialog and Class to set the root password if it + * is not empty. + * \code + * if(PasswordDialogImpl::needDialog()) { + * PasswordDialogImpl *dia = new PasswordDialogImpl() + * dia->exec(); + * dia->delete(); + * } + */ +class PasswordDialogImpl : public PasswordDialog { + Q_OBJECT +public: + PasswordDialogImpl( QWidget *parent ); + ~PasswordDialogImpl(); + static bool needDialog(); + +protected slots: + void done( int ); + void slotToggleEcho( bool ); + +private: + void writePassword(); + void writeShadow(); + void error( const QString&, const QString& ); + bool m_isSet : 1; +}; + + +#endif -- cgit v0.9.0.2