summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/opie-login/passworddialogimpl.cpp7
1 files changed, 6 insertions, 1 deletions
diff --git a/core/opie-login/passworddialogimpl.cpp b/core/opie-login/passworddialogimpl.cpp
index 852708e..d9132e2 100644
--- a/core/opie-login/passworddialogimpl.cpp
+++ b/core/opie-login/passworddialogimpl.cpp
@@ -1,232 +1,237 @@
1/* 1/*
2               =. This file is part of the OPIE Project 2               =. This file is part of the OPIE Project
3             .=l. Copyright (c) 2004 Holger Hans Peter Freyther <zecke@handhelds.org> 3             .=l. Copyright (c) 2004 Holger Hans Peter Freyther <zecke@handhelds.org>
4           .>+-= 4           .>+-=
5 _;:,     .>    :=|. This file is free software; you can 5 _;:,     .>    :=|. This file is free software; you can
6.> <`_,   >  .   <= redistribute it and/or modify it under 6.> <`_,   >  .   <= redistribute it and/or modify it under
7:`=1 )Y*s>-.--   : the terms of the GNU General Public 7:`=1 )Y*s>-.--   : the terms of the GNU General Public
8.="- .-=="i,     .._ License as published by the Free Software 8.="- .-=="i,     .._ License as published by the Free Software
9 - .   .-<_>     .<> Foundation; either version 2 of the License, 9 - .   .-<_>     .<> Foundation; either version 2 of the License,
10     ._= =}       : or (at your option) any later version. 10     ._= =}       : or (at your option) any later version.
11    .%`+i>       _;_. 11    .%`+i>       _;_.
12    .i_,=:_.      -<s. This file is distributed in the hope that 12    .i_,=:_.      -<s. This file is distributed in the hope that
13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY; 13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
14    : ..    .:,     . . . without even the implied warranty of 14    : ..    .:,     . . . without even the implied warranty of
15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A 15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General 16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General
17..}^=.=       =       ; Public License for more details. 17..}^=.=       =       ; Public License for more details.
18++=   -.     .`     .: 18++=   -.     .`     .:
19 :     =  ...= . :.=- You should have received a copy of the GNU 19 :     =  ...= . :.=- You should have received a copy of the GNU
20 -.   .:....=;==+<; General Public License along with this file; 20 -.   .:....=;==+<; General Public License along with this file;
21  -_. . .   )=.  = see the file COPYING. If not, write to the 21  -_. . .   )=.  = see the file COPYING. If not, write to the
22    --        :-=` Free Software Foundation, Inc., 22    --        :-=` Free Software Foundation, Inc.,
23 59 Temple Place - Suite 330, 23 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA. 24 Boston, MA 02111-1307, USA.
25 25
26*/ 26*/
27 27
28
29#include <qlayout.h> 28#include <qlayout.h>
30#include <qlabel.h> 29#include <qlabel.h>
31#include <qlineedit.h> 30#include <qlineedit.h>
32#include <qvalidator.h> 31#include <qvalidator.h>
33#include <qmessagebox.h> 32#include <qmessagebox.h>
34#include <qhbox.h> 33#include <qhbox.h>
35#include <qtoolbutton.h> 34#include <qtoolbutton.h>
36 35
36
37
37#include <sys/types.h> 38#include <sys/types.h>
38#include <pwd.h> 39#include <pwd.h>
39#include <shadow.h> 40#include <shadow.h>
40#include <stdio.h> 41#include <stdio.h>
41#include <time.h> 42#include <time.h>
42#include <unistd.h> 43#include <unistd.h>
43 44
45// Shitty gcc2 toolchain
46extern "C" char* crypt( const char*, const char* );
47
48
44 49
45#include "passworddialogimpl.h" 50#include "passworddialogimpl.h"
46 51
47 52
48// This function is taken from 'busybox'. 53// This function is taken from 'busybox'.
49static int i64c(int i) { 54static int i64c(int i) {
50 if (i <= 0) 55 if (i <= 0)
51 return ('.'); 56 return ('.');
52 if (i == 1) 57 if (i == 1)
53 return ('/'); 58 return ('/');
54 if (i >= 2 && i < 12) 59 if (i >= 2 && i < 12)
55 return ('0' - 2 + i); 60 return ('0' - 2 + i);
56 if (i >= 12 && i < 38) 61 if (i >= 12 && i < 38)
57 return ('A' - 12 + i); 62 return ('A' - 12 + i);
58 if (i >= 38 && i < 63) 63 if (i >= 38 && i < 63)
59 return ('a' - 38 + i); 64 return ('a' - 38 + i);
60 return ('z'); 65 return ('z');
61} 66}
62 67
63// This function is taken from 'busybox'. 68// This function is taken from 'busybox'.
64static char *crypt_make_salt() { 69static char *crypt_make_salt() {
65 time_t now; 70 time_t now;
66 static unsigned long x; 71 static unsigned long x;
67 static char result[3]; 72 static char result[3];
68 73
69 ::time(&now); 74 ::time(&now);
70 x += now + getpid() + clock(); 75 x += now + getpid() + clock();
71 result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077); 76 result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077);
72 result[1] = i64c(((x >> 12) ^ x) & 077); 77 result[1] = i64c(((x >> 12) ^ x) & 077);
73 result[2] = '\0'; 78 result[2] = '\0';
74 return result; 79 return result;
75} 80}
76 81
77/* 82/*
78 * Modal dialog to force root password. It is quite hard as it only leave 83 * Modal dialog to force root password. It is quite hard as it only leave
79 * when a password is set. 84 * when a password is set.
80 * Also it prevalidates the password... 85 * Also it prevalidates the password...
81 */ 86 */
82PasswordDialogImpl::PasswordDialogImpl( QWidget* parent ) 87PasswordDialogImpl::PasswordDialogImpl( QWidget* parent )
83 : PasswordDialog( parent, 0, true ), m_isSet( PasswordDialogImpl::needDialog() ) { 88 : PasswordDialog( parent, 0, true ), m_isSet( PasswordDialogImpl::needDialog() ) {
84} 89}
85 90
86PasswordDialogImpl::~PasswordDialogImpl() { 91PasswordDialogImpl::~PasswordDialogImpl() {
87 /* qt does the stuff for us */ 92 /* qt does the stuff for us */
88} 93}
89 94
90void PasswordDialogImpl::done(int res) { 95void PasswordDialogImpl::done(int res) {
91 m_isSet = true; 96 m_isSet = true;
92 97
93 /* 98 /*
94 * The user hit 'Ok' see if we can safe the file 99 * The user hit 'Ok' see if we can safe the file
95 * if not an error will be raised and m_isSet altered. 100 * if not an error will be raised and m_isSet altered.
96 * On cancel we will see if it is now ok... 101 * On cancel we will see if it is now ok...
97 */ 102 */
98 if ( res == Accepted ) 103 if ( res == Accepted )
99 writePassword(); 104 writePassword();
100 else if(PasswordDialogImpl::needDialog() ) { 105 else if(PasswordDialogImpl::needDialog() ) {
101 switch( QMessageBox::warning(this,tr("Trying to leave without password set") , 106 switch( QMessageBox::warning(this,tr("Trying to leave without password set") ,
102 tr("<qt>No password was set. This could lead to you not beeing" 107 tr("<qt>No password was set. This could lead to you not beeing"
103 "able to remotely connect to your machine." 108 "able to remotely connect to your machine."
104 "Do you want to continue not setting a password?</qt>" ), 109 "Do you want to continue not setting a password?</qt>" ),
105 QMessageBox::Ok, QMessageBox::Cancel ) ) { 110 QMessageBox::Ok, QMessageBox::Cancel ) ) {
106 case QMessageBox::Cancel: 111 case QMessageBox::Cancel:
107 m_isSet = false; 112 m_isSet = false;
108 break; 113 break;
109 case QMessageBox::Ok: 114 case QMessageBox::Ok:
110 default: 115 default:
111 break; 116 break;
112 } 117 }
113 118
114 } 119 }
115 120
116 if(m_isSet) 121 if(m_isSet)
117 PasswordDialog::done( res ); 122 PasswordDialog::done( res );
118} 123}
119 124
120/* 125/*
121 * Lets see if we can write either shadow 126 * Lets see if we can write either shadow
122 * 127 *
123 */ 128 */
124/** 129/**
125 * CRYPT the password and then tries to write it either to the shadow password 130 * CRYPT the password and then tries to write it either to the shadow password
126 * or to the plain /etc/passwd 131 * or to the plain /etc/passwd
127 */ 132 */
128void PasswordDialogImpl::writePassword() { 133void PasswordDialogImpl::writePassword() {
129 /* 134 /*
130 * Check if both texts are the same 135 * Check if both texts are the same
131 */ 136 */
132 if ( m_pass->text() != m_confirm->text() ) 137 if ( m_pass->text() != m_confirm->text() )
133 return error( tr("Passwords don't match"), 138 return error( tr("Passwords don't match"),
134 tr("<qt>The two passwords don't match. Please try again.</qt>") ); 139 tr("<qt>The two passwords don't match. Please try again.</qt>") );
135 140
136 141
137 /* 142 /*
138 * Now crypt the password so we can write it later 143 * Now crypt the password so we can write it later
139 */ 144 */
140 char* password = ::crypt( m_pass->text().latin1(), crypt_make_salt() ); 145 char* password = ::crypt( m_pass->text().latin1(), crypt_make_salt() );
141 146
142 if ( !password ) 147 if ( !password )
143 return error( tr("Password not legal" ), 148 return error( tr("Password not legal" ),
144 tr("<qt>The entered password is not a valid password." 149 tr("<qt>The entered password is not a valid password."
145 "Please try entering a valid password.</qt>" ) ); 150 "Please try entering a valid password.</qt>" ) );
146 151
147 /* rewind and rewrite the password file */ 152 /* rewind and rewrite the password file */
148 ::setpwent(); 153 ::setpwent();
149 154
150 FILE* file = ::fopen( "/etc/passwd.new", "w" ); 155 FILE* file = ::fopen( "/etc/passwd.new", "w" );
151 struct passwd* pass; 156 struct passwd* pass;
152 while ( (pass = ::getpwent()) != 0l ) { 157 while ( (pass = ::getpwent()) != 0l ) {
153 /* no shadow password support */ 158 /* no shadow password support */
154 if ( pass->pw_uid == 0 ) 159 if ( pass->pw_uid == 0 )
155 pass->pw_passwd = password; 160 pass->pw_passwd = password;
156 161
157 ::putpwent( pass, file ); 162 ::putpwent( pass, file );
158 } 163 }
159 164
160 ::fclose( file ); 165 ::fclose( file );
161 ::endpwent(); 166 ::endpwent();
162 ::rename("/etc/passwd.new","/etc/passwd" ); 167 ::rename("/etc/passwd.new","/etc/passwd" );
163 168
164 /* should be done now */ 169 /* should be done now */
165#ifdef OPIE_LOGIN_SHADOW_PW 170#ifdef OPIE_LOGIN_SHADOW_PW
166 #error "Can't write Shadow Passwords fixme" 171 #error "Can't write Shadow Passwords fixme"
167#endif 172#endif
168} 173}
169 174
170/** 175/**
171 * Raise an error. Delete input and set the focus after showing 176 * Raise an error. Delete input and set the focus after showing
172 * the error to the user 177 * the error to the user
173 */ 178 */
174void PasswordDialogImpl::error( const QString& caption, const QString& text ) { 179void PasswordDialogImpl::error( const QString& caption, const QString& text ) {
175 m_isSet = false; 180 m_isSet = false;
176 QMessageBox::critical(this,caption, text, 181 QMessageBox::critical(this,caption, text,
177 QMessageBox::Ok, QMessageBox::NoButton ); 182 QMessageBox::Ok, QMessageBox::NoButton );
178 183
179 m_pass->setText(""); 184 m_pass->setText("");
180 m_pass->setFocus(); 185 m_pass->setFocus();
181 186
182 m_confirm->setText(""); 187 m_confirm->setText("");
183} 188}
184 189
185void PasswordDialogImpl::slotToggleEcho( bool b ) { 190void PasswordDialogImpl::slotToggleEcho( bool b ) {
186 m_pass-> setEchoMode( b ? QLineEdit::Normal : QLineEdit::Password ); 191 m_pass-> setEchoMode( b ? QLineEdit::Normal : QLineEdit::Password );
187 m_confirm->setEchoMode( b ? QLineEdit::Normal : QLineEdit::Password ); 192 m_confirm->setEchoMode( b ? QLineEdit::Normal : QLineEdit::Password );
188} 193}
189 194
190///////////////////////// 195/////////////////////////
191/// static functions 196/// static functions
192/// 197///
193 198
194/** 199/**
195 * Ask whether or not we need to show the dialog. It returns true if 200 * Ask whether or not we need to show the dialog. It returns true if
196 * no root password is set so that the user will be able to set one. 201 * no root password is set so that the user will be able to set one.
197 */ 202 */
198bool PasswordDialogImpl::needDialog() { 203bool PasswordDialogImpl::needDialog() {
199 /* 204 /*
200 * This can cope with no password and shadow passwords 205 * This can cope with no password and shadow passwords
201 * Let us go through the user database until we find 'root' and then 206 * Let us go through the user database until we find 'root' and then
202 * see if it is 'shadow' and see if shadow is empty or see if the password is empty 207 * see if it is 'shadow' and see if shadow is empty or see if the password is empty
203 */ 208 */
204 bool need = false; 209 bool need = false;
205 struct passwd *pwd; 210 struct passwd *pwd;
206 ::setpwent(); 211 ::setpwent();
207 212
208 while((pwd = ::getpwent() ) ) { 213 while((pwd = ::getpwent() ) ) {
209 /* found root */ 214 /* found root */
210 if( pwd->pw_uid == 0 ) { 215 if( pwd->pw_uid == 0 ) {
211 QString str = QString::fromLatin1(pwd->pw_passwd ); 216 QString str = QString::fromLatin1(pwd->pw_passwd );
212 217
213 /* 218 /*
214 * If str is really empty it is passwordless anyway... or '*' is a hint to set one 219 * If str is really empty it is passwordless anyway... or '*' is a hint to set one
215 * on OE/Familiar 220 * on OE/Familiar
216 * else it is shadow based 221 * else it is shadow based
217 */ 222 */
218 if(str.isEmpty() || str == '*' ) 223 if(str.isEmpty() || str == '*' )
219 need = true; 224 need = true;
220 else if ( str == 'x' ) 225 else if ( str == 'x' )
221#ifdef OPIE_LOGIN_SHADOW_PW 226#ifdef OPIE_LOGIN_SHADOW_PW
222 need = QString::fromLatin1( ::getspnam( pwd->pw_name )->sp_pwdp ).isEmpty(); 227 need = QString::fromLatin1( ::getspnam( pwd->pw_name )->sp_pwdp ).isEmpty();
223#else 228#else
224 ; 229 ;
225#endif 230#endif
226 break; 231 break;
227 } 232 }
228 } 233 }
229 ::endpwent(); 234 ::endpwent();
230 235
231 return need; 236 return need;
232} 237}