summaryrefslogtreecommitdiff
path: root/core/opie-login/loginwindowimpl.cpp
Unidiff
Diffstat (limited to 'core/opie-login/loginwindowimpl.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/opie-login/loginwindowimpl.cpp270
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
@@ -13,27 +13,15 @@
13 13
14#include <qpe/resource.h> 14#include <qpe/resource.h>
15#include <qpe/qcopenvelope_qws.h> 15#include <qpe/qcopenvelope_qws.h>
16#include <qpe/config.h>
16 17
17#include <opie/odevice.h> 18#include <opie/odevice.h>
18 19
19#include <stdio.h> 20#include <stdio.h>
20
21#include <pwd.h>
22#include <grp.h>
23#include <unistd.h>
24#include <stdlib.h> 21#include <stdlib.h>
25#include <signal.h>
26
27#ifdef USEPAM
28extern "C" {
29#include <security/pam_appl.h>
30}
31#else
32#include <crypt.h>
33#include <shadow.h>
34#endif
35 22
36#include "loginwindowimpl.h" 23#include "loginwindowimpl.h"
24#include "loginapplication.h"
37#include "inputmethods.h" 25#include "inputmethods.h"
38 26
39using namespace Opie; 27using namespace Opie;
@@ -54,7 +42,7 @@ LoginWindowImpl::LoginWindowImpl ( ) : LoginWindow ( 0, "LOGIN-WINDOW", WStyle_C
54 setActiveWindow ( ); 42 setActiveWindow ( );
55 m_password-> setFocus ( ); 43 m_password-> setFocus ( );
56 44
57 m_user-> insertStringList ( getAllUsers ( )); 45 m_user-> insertStringList ( lApp-> allUsers ( ));
58 46
59 QTimer::singleShot ( 0, this, SLOT( showIM ( ))); 47 QTimer::singleShot ( 0, this, SLOT( showIM ( )));
60 48
@@ -65,6 +53,13 @@ LoginWindowImpl::LoginWindowImpl ( ) : LoginWindow ( 0, "LOGIN-WINDOW", WStyle_C
65 setBackgroundPixmap ( bgpix ); 53 setBackgroundPixmap ( bgpix );
66 54
67 m_caption-> setText ( m_caption-> text ( ) + tr( "<center>%1 %2</center>" ). arg ( ODevice::inst ( )-> systemString ( )). arg ( ODevice::inst ( )-> systemVersionString ( ))); 55 m_caption-> setText ( m_caption-> text ( ) + tr( "<center>%1 %2</center>" ). arg ( ODevice::inst ( )-> systemString ( )). arg ( ODevice::inst ( )-> systemVersionString ( )));
56
57 Config cfg ( "opie-login" );
58 cfg. setGroup ( "General" );
59 QString last = cfg. readEntry ( "LastLogin" );
60
61 if ( !last. isEmpty ( ))
62 m_user-> setEditText ( last );
68} 63}
69 64
70LoginWindowImpl::~LoginWindowImpl ( ) 65LoginWindowImpl::~LoginWindowImpl ( )
@@ -90,22 +85,6 @@ void LoginWindowImpl::toggleEchoMode ( bool t )
90 m_password-> setEchoMode ( t ? QLineEdit::Normal : QLineEdit::Password ); 85 m_password-> setEchoMode ( t ? QLineEdit::Normal : QLineEdit::Password );
91} 86}
92 87
93
94QStringList LoginWindowImpl::getAllUsers ( )
95{
96 struct passwd *pwd;
97 QStringList sl;
98
99 while (( pwd = ::getpwent ( ))) {
100 if (( pwd-> pw_uid == 0 ) || ( pwd-> pw_uid >= 500 && pwd-> pw_uid < 65534 ))
101 sl << QString ( pwd-> pw_name );
102 }
103
104 ::endpwent ( );
105
106 return sl;
107}
108
109void LoginWindowImpl::showIM ( ) 88void LoginWindowImpl::showIM ( )
110{ 89{
111 m_input-> showInputMethod ( ); 90 m_input-> showInputMethod ( );
@@ -118,8 +97,7 @@ void LoginWindowImpl::restart ( )
118 97
119void LoginWindowImpl::quit ( ) 98void LoginWindowImpl::quit ( )
120{ 99{
121 qApp-> quit ( ); 100 lApp-> quitToConsole ( );
122 ::kill ( ::getppid ( ), SIGUSR1 );
123} 101}
124 102
125void LoginWindowImpl::suspend ( ) 103void LoginWindowImpl::suspend ( )
@@ -136,207 +114,61 @@ void LoginWindowImpl::backlight ( )
136 e << -2; // toggle 114 e << -2; // toggle
137} 115}
138 116
139#ifdef USEPAM 117class WaitLogo : public QLabel {
140 118public:
141static const char *_PAM_SERVICE = "xdm"; 119 WaitLogo ( ) : QLabel ( 0, "wait hack!", WStyle_Customize | WStyle_NoBorder | WStyle_Tool )
142static const char *PAM_password; 120 {
143 121 QImage img = Resource::loadImage ( "launcher/new_wait" );
144typedef const struct pam_message pam_message_type; 122 QPixmap pix;
145 123 pix. convertFromImage ( img );
146static int PAM_conv( int, pam_message_type **, struct pam_response **, void * ); 124 setPixmap ( pix );
147 125 setAlignment ( AlignCenter );
148static struct pam_conv PAM_conversation = { 126 move ( 0, 0 );
149 &PAM_conv, 127 resize ( qApp-> desktop ( )-> width ( ), qApp-> desktop ( )-> height ( ));
150 NULL 128
151}; 129 m_visible = false;
152 130 show ( );
153//----------------------------------------------------------------------------
154
155static char *COPY_STRING( const char * s ) {
156 return (s) ? strdup(s) : (char *)NULL;
157}
158
159#define GET_MEM if (reply) realloc(reply, size);\
160 else reply = (struct pam_response *)malloc(size); \
161 if (!reply) return PAM_CONV_ERR; \
162 size += sizeof(struct pam_response)
163
164
165static int PAM_conv( int num_msg, pam_message_type **msg,
166 struct pam_response **resp, void *)
167{
168 int count = 0, replies = 0;
169 struct pam_response *reply = NULL;
170 int size = sizeof(struct pam_response);
171
172 for( count = 0; count < num_msg; count++ ) {
173 switch (msg[count]->msg_style) {
174 case PAM_PROMPT_ECHO_ON:
175 /* user name given to PAM already */
176 return PAM_CONV_ERR;
177
178 case PAM_PROMPT_ECHO_OFF:
179 /* wants password */
180 GET_MEM;
181 reply[replies].resp_retcode = PAM_SUCCESS;
182 reply[replies].resp = COPY_STRING(PAM_password);
183 replies++;
184 /* PAM frees resp */
185 break;
186 case PAM_TEXT_INFO:
187 break;
188 default:
189 /* unknown or PAM_ERROR_MSG */
190 if (reply) free (reply);
191 return PAM_CONV_ERR;
192 }
193 }
194 if (reply) *resp = reply;
195 return PAM_SUCCESS;
196}
197
198
199static bool pwcheck_PAM( const char *user, const char *password )
200{
201 bool pw_correct = false;
202 int pam_error;
203 int pam_return = 0;
204 pam_handle_t *pamh = 0;
205 PAM_password = password;
206
207 pam_error = pam_start( _PAM_SERVICE, user, &PAM_conversation, &pamh );
208 if( pam_error == PAM_SUCCESS ) {
209 pam_error = pam_authenticate( pamh, 0 );
210 if( pam_error == PAM_SUCCESS ) {
211 //-- password correct
212 pw_correct = true;
213 pam_return = PAM_SUCCESS;
214 } else {
215 pam_return = pam_error;
216 }
217 } else {
218 // cerr << "PAM error: " << pam_strerror( pamh, pam_error ) << endl;
219 }
220 pam_end( pamh, pam_return );
221 return pw_correct;
222}
223
224#else
225
226//----------------------------------------------------------------------------
227
228static bool pwcheck_Unix( const char *user, const char *pass )
229{
230 char *encrypted, *correct;
231 struct passwd *pw;
232
233 if ( !user || !pass )
234 return false;
235
236 pw = getpwnam ( user );
237
238 if ( !pw )
239 return false;
240
241 if (( strcmp ( pw-> pw_passwd, "x" ) == 0 ) || ( strcmp ( pw-> pw_passwd, "*" ) == 0 )) {
242 struct spwd *sp = getspnam ( pw-> pw_name );
243
244 if ( !sp )
245 return false;
246
247 correct = sp-> sp_pwdp;
248 } 131 }
249 else
250 correct = pw-> pw_passwd;
251
252 if ( correct == 0 || correct[0] == '\0' )
253 return true;
254 132
255 encrypted = crypt ( pass, correct ); 133 virtual void showEvent ( QShowEvent *e )
256 return ( strcmp ( encrypted, correct ) == 0 ); 134 {
257} 135 QLabel::showEvent ( e );
258 136 m_visible = true;
259#endif 137 }
260
261
262bool LoginWindowImpl::changeIdentity ( const char *user )
263{
264 const char *DEFAULT_LOGIN_PATH = "/bin:/usr/bin";
265 const char *DEFAULT_ROOT_LOGIN_PATH = "/usr/sbin:/bin:/usr/bin:/sbin";
266
267 bool fail = false;
268 struct passwd *pw = getpwnam ( user );
269
270 fail |= ( pw == 0 );
271 fail |= ( initgroups ( pw-> pw_name, pw-> pw_gid ));
272 endgrent ( );
273 fail |= ( setgid ( pw-> pw_gid ));
274 fail |= ( setuid ( pw-> pw_uid ));
275
276 fail |= ( chdir ( pw-> pw_dir ) && chdir ( "/" ));
277 138
278 fail |= ( setenv ( "HOME", pw-> pw_dir, 1 )); 139 virtual void paintEvent ( QPaintEvent *e )
279 fail |= ( setenv ( "SHELL", pw-> pw_shell, 1 )); 140 {
280 fail |= ( setenv ( "USER", pw-> pw_name, 1 )); 141 QLabel::paintEvent ( e );
281 fail |= ( setenv ( "LOGNAME", pw-> pw_name, 1 )); 142 if ( m_visible )
282 fail |= ( setenv ( "PATH", ( pw-> pw_uid ? DEFAULT_LOGIN_PATH : DEFAULT_ROOT_LOGIN_PATH ), 1 )); 143 qApp-> quit ( );
144 }
283 145
284 return !fail; 146private:
285} 147 bool m_visible;
148};
286 149
287void LoginWindowImpl::login ( ) 150void LoginWindowImpl::login ( )
288{ 151{
289 const char *user = ::strdup ( m_user-> currentText ( ). local8Bit ( )); 152 const char *user = ::strdup ( m_user-> currentText ( ). local8Bit ( ));
290 const char *pass = ::strdup ( m_password-> text ( ). local8Bit ( )); 153 const char *pass = ::strdup ( m_password-> text ( ). local8Bit ( ));
291 bool ok;
292 154
293 if ( !user || !user [0] ) 155 if ( !user || !user [0] )
294 return; 156 return;
295 if ( !pass ) 157 if ( !pass )
296 pass = ""; 158 pass = "";
297 159
298#if defined( USEPAM ) 160 if ( lApp-> checkPassword ( user, pass )) {
299 ok = pwcheck_PAM ( user, pass ); 161 Config cfg ( "opie-login" );
300#else 162 cfg. setGroup ( "General" );
301 ok = pwcheck_Unix ( user, pass ); 163 cfg. writeEntry ( "LastLogin", user );
302#endif 164 cfg. write ( );
303 165
304 if ( ok ) { 166 lApp-> setLoginAs ( user );
305 if ( changeIdentity ( user )) { 167
306 // Draw a big wait icon, the image can be altered in later revisions 168 // Draw a big wait icon, the image can be altered in later revisions
307 QWidget *d = QApplication::desktop ( ); 169 m_input-> hideInputMethod ( );
308 m_input-> hideInputMethod ( ); 170 new WaitLogo ( );
309 171 // WaitLogo::showEvent() calls qApp-> quit()
310 QImage img = Resource::loadImage( "launcher/new_wait" );
311 QPixmap pix;
312 pix. convertFromImage ( img );
313 QLabel *w = new QLabel ( 0, "wait hack!", WStyle_Customize | WStyle_NoBorder | WStyle_Tool );
314 w-> setPixmap ( pix );
315 w-> setAlignment ( AlignCenter );
316 w-> showMaximized ( );
317 qApp-> processEvents ( );
318
319 char *opie = ::getenv ( "OPIEDIR" );
320 char *arg = new char [::strlen ( opie ) + 8 + 1];
321
322 ::strcpy ( arg, opie );
323 ::strcat ( arg, "/bin/qpe" );
324
325 // start qpe via a login shell
326 ::execl ( "/bin/sh", "-sh", "-c", arg, 0 );
327
328 w-> hide ( );
329 delete w;
330
331 QMessageBox::critical ( this, tr( "Failure" ), tr( "Could not start OPIE\n(%1)." ). arg ( arg ));
332 delete [] arg;
333
334 restart ( );
335 }
336 else {
337 QMessageBox::critical ( this, tr( "Failure" ), tr( "Could not switch to new user identity" ));
338 restart ( );
339 }
340 } 172 }
341 else { 173 else {
342 QMessageBox::warning ( this, tr( "Wrong password" ), tr( "The given password is incorrect." )); 174 QMessageBox::warning ( this, tr( "Wrong password" ), tr( "The given password is incorrect." ));