summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/qcopbridge.cpp322
1 files changed, 161 insertions, 161 deletions
diff --git a/core/launcher/qcopbridge.cpp b/core/launcher/qcopbridge.cpp
index c78e827..c8af919 100644
--- a/core/launcher/qcopbridge.cpp
+++ b/core/launcher/qcopbridge.cpp
@@ -32,385 +32,385 @@
32#include <qfileinfo.h> 32#include <qfileinfo.h>
33#include <qregexp.h> 33#include <qregexp.h>
34#include <qcopchannel_qws.h> 34#include <qcopchannel_qws.h>
35 35
36#define _XOPEN_SOURCE 36#define _XOPEN_SOURCE
37#include <pwd.h> 37#include <pwd.h>
38#include <sys/types.h> 38#include <sys/types.h>
39#include <unistd.h> 39#include <unistd.h>
40 40
41#if defined(_OS_LINUX_) 41#if defined(_OS_LINUX_)
42#include <shadow.h> 42#include <shadow.h>
43#endif 43#endif
44 44
45//#define INSECURE 45//#define INSECURE
46 46
47const int block_size = 51200; 47const int block_size = 51200;
48 48
49QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent = 0, 49QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent = 0,
50 const char* name = 0) 50 const char* name = 0)
51 : QServerSocket( port, 1, parent, name ), 51 : QServerSocket( port, 1, parent, name ),
52 desktopChannel( 0 ), 52 desktopChannel( 0 ),
53 cardChannel( 0 ) 53 cardChannel( 0 )
54{ 54{
55 if ( !ok() ) 55 if ( !ok() )
56 qWarning( "Failed to bind to port %d", port ); 56 qWarning( "Failed to bind to port %d", port );
57 else { 57 else {
58 desktopChannel = new QCopChannel( "QPE/Desktop", this ); 58 desktopChannel = new QCopChannel( "QPE/Desktop", this );
59 connect( desktopChannel, SIGNAL(received(const QCString &, const QByteArray &)), 59 connect( desktopChannel, SIGNAL(received(const QCString &, const QByteArray &)),
60 this, SLOT(desktopMessage( const QCString &, const QByteArray &)) ); 60 this, SLOT(desktopMessage( const QCString &, const QByteArray &)) );
61 cardChannel = new QCopChannel( "QPE/Card", this ); 61 cardChannel = new QCopChannel( "QPE/Card", this );
62 connect( cardChannel, SIGNAL(received(const QCString &, const QByteArray &)), 62 connect( cardChannel, SIGNAL(received(const QCString &, const QByteArray &)),
63 this, SLOT(desktopMessage( const QCString &, const QByteArray &)) ); 63 this, SLOT(desktopMessage( const QCString &, const QByteArray &)) );
64 } 64 }
65 sendSync = FALSE; 65 sendSync = FALSE;
66} 66}
67 67
68QCopBridge::~QCopBridge() 68QCopBridge::~QCopBridge()
69{ 69{
70 delete desktopChannel; 70 delete desktopChannel;
71} 71}
72 72
73void QCopBridge::newConnection( int socket ) 73void QCopBridge::newConnection( int socket )
74{ 74{
75 QCopBridgePI *pi = new QCopBridgePI( socket, this ); 75 QCopBridgePI *pi = new QCopBridgePI( socket, this );
76 openConnections.append( pi ); 76 openConnections.append( pi );
77 connect ( pi, SIGNAL( connectionClosed( QCopBridgePI *) ), this, SLOT( connectionClosed( QCopBridgePI *) ) ); 77 connect ( pi, SIGNAL( connectionClosed( QCopBridgePI *) ), this, SLOT( connectionClosed( QCopBridgePI *) ) );
78 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::DisableSuspend; 78 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::DisableSuspend;
79 79
80 if ( sendSync ) { 80 if ( sendSync ) {
81 pi ->startSync(); 81 pi ->startSync();
82 sendSync = FALSE; 82 sendSync = FALSE;
83 } 83 }
84} 84}
85 85
86void QCopBridge::connectionClosed( QCopBridgePI *pi ) 86void QCopBridge::connectionClosed( QCopBridgePI *pi )
87{ 87{
88 openConnections.remove( pi ); 88 openConnections.remove( pi );
89 if ( openConnections.count() == 0 ) { 89 if ( openConnections.count() == 0 ) {
90 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable; 90 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
91 } 91 }
92} 92}
93 93
94void QCopBridge::closeOpenConnections() 94void QCopBridge::closeOpenConnections()
95{ 95{
96 QCopBridgePI *pi; 96 QCopBridgePI *pi;
97 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) 97 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() )
98 pi->close(); 98 pi->close();
99} 99}
100 100
101 101
102void QCopBridge::desktopMessage( const QCString &command, const QByteArray &args ) 102void QCopBridge::desktopMessage( const QCString &command, const QByteArray &args )
103{ 103{
104 command.stripWhiteSpace(); 104 command.stripWhiteSpace();
105 105
106 int paren = command.find( "(" ); 106 int paren = command.find( "(" );
107 if ( paren <= 0 ) { 107 if ( paren <= 0 ) {
108 qDebug("DesktopMessage: bad qcop syntax"); 108 qDebug("DesktopMessage: bad qcop syntax");
109 return; 109 return;
110 } 110 }
111 111
112 QString params = command.mid( paren + 1 ); 112 QString params = command.mid( paren + 1 );
113 if ( params[params.length()-1] != ')' ) { 113 if ( params[params.length()-1] != ')' ) {
114 qDebug("DesktopMessage: bad qcop syntax"); 114 qDebug("DesktopMessage: bad qcop syntax");
115 return; 115 return;
116 } 116 }
117 117
118 params.truncate( params.length()-1 ); 118 params.truncate( params.length()-1 );
119 119
120 QStringList paramList = QStringList::split( ",", params ); 120 QStringList paramList = QStringList::split( ",", params );
121 QString data; 121 QString data;
122 if ( paramList.count() ) { 122 if ( paramList.count() ) {
123 QDataStream stream( args, IO_ReadOnly ); 123 QDataStream stream( args, IO_ReadOnly );
124 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) { 124 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) {
125 QString str; 125 QString str;
126 if ( *it == "QString" ) { 126 if ( *it == "QString" ) {
127 stream >> str; 127 stream >> str;
128 } else if ( *it == "QCString" ) { 128 } else if ( *it == "QCString" ) {
129 QCString cstr; 129 QCString cstr;
130 stream >> cstr; 130 stream >> cstr;
131 str = QString::fromLocal8Bit( cstr ); 131 str = QString::fromLocal8Bit( cstr );
132 } else if ( *it == "int" ) { 132 } else if ( *it == "int" ) {
133 int i; 133 int i;
134 stream >> i; 134 stream >> i;
135 str = QString::number( i ); 135 str = QString::number( i );
136 } else if ( *it == "bool" ) { 136 } else if ( *it == "bool" ) {
137 int i; 137 int i;
138 stream >> i; 138 stream >> i;
139 str = QString::number( i ); 139 str = QString::number( i );
140 } else { 140 } else {
141 qDebug(" cannot route the argument type %s throught the qcop bridge", (*it).latin1() ); 141 qDebug(" cannot route the argument type %s through the qcop bridge", (*it).latin1() );
142 return; 142 return;
143 } 143 }
144 str.replace( QRegExp("&"), "&amp;" ); 144 str.replace( QRegExp("&"), "&amp;" );
145 str.replace( QRegExp(" "), "&0x20;" ); 145 str.replace( QRegExp(" "), "&0x20;" );
146 str.replace( QRegExp("\n"), "&0x0d;" ); 146 str.replace( QRegExp("\n"), "&0x0d;" );
147 str.replace( QRegExp("\r"), "&0x0a;" ); 147 str.replace( QRegExp("\r"), "&0x0a;" );
148 data += " " + str; 148 data += " " + str;
149 } 149 }
150 } 150 }
151 QString sendCommand = QString(command.data()) + data; 151 QString sendCommand = QString(command.data()) + data;
152 // send the command to all open connections 152 // send the command to all open connections
153 if ( command == "startSync()" ) { 153 if ( command == "startSync()" ) {
154 // we need to buffer it a bit 154 // we need to buffer it a bit
155 sendSync = TRUE; 155 sendSync = TRUE;
156 startTimer( 20000 ); 156 startTimer( 20000 );
157 } 157 }
158 158
159 QCopBridgePI *pi; 159 QCopBridgePI *pi;
160 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) { 160 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) {
161 pi->sendDesktopMessage( sendCommand ); 161 pi->sendDesktopMessage( sendCommand );
162 } 162 }
163} 163}
164 164
165void QCopBridge::timerEvent( QTimerEvent * ) 165void QCopBridge::timerEvent( QTimerEvent * )
166{ 166{
167 sendSync = FALSE; 167 sendSync = FALSE;
168 killTimers(); 168 killTimers();
169} 169}
170 170
171 171
172QCopBridgePI::QCopBridgePI( int socket, QObject *parent = 0, const char* name = 0 ) 172QCopBridgePI::QCopBridgePI( int socket, QObject *parent = 0, const char* name = 0 )
173 : QSocket( parent, name ) 173 : QSocket( parent, name )
174{ 174{
175 setSocket( socket ); 175 setSocket( socket );
176 176
177 peerport = peerPort(); 177 peerport = peerPort();
178 peeraddress = peerAddress(); 178 peeraddress = peerAddress();
179 179
180#ifndef INSECURE 180#ifndef INSECURE
181 if ( !accessAuthorized(peeraddress) ) { 181 if ( !accessAuthorized(peeraddress) ) {
182 state = Forbidden; 182 state = Forbidden;
183 startTimer( 0 ); 183 startTimer( 0 );
184 } else 184 } else
185 #endif 185#endif
186 { 186 {
187 state = Connected; 187 state = Connected;
188 sendSync = FALSE; 188 sendSync = FALSE;
189 connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); 189 connect( this, SIGNAL( readyRead() ), SLOT( read() ) );
190 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); 190 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
191 191
192 send( "220 Qtopia QCop bridge ready!" ); 192 send( "220 Qtopia QCop bridge ready!" );
193 state = Wait_USER; 193 state = Wait_USER;
194 194
195 // idle timer to close connections when not used anymore 195 // idle timer to close connections when not used anymore
196 startTimer( 60000 ); 196 startTimer( 60000 );
197 connected = TRUE; 197 connected = TRUE;
198 } 198 }
199} 199}
200 200
201 201
202QCopBridgePI::~QCopBridgePI() 202QCopBridgePI::~QCopBridgePI()
203{ 203{
204 204
205} 205}
206 206
207void QCopBridgePI::connectionClosed() 207void QCopBridgePI::connectionClosed()
208{ 208{
209 emit connectionClosed( this ); 209 emit connectionClosed( this );
210 // qDebug( "Debug: Connection closed" ); 210 // qDebug( "Debug: Connection closed" );
211 delete this; 211 delete this;
212} 212}
213 213
214void QCopBridgePI::sendDesktopMessage( const QString &msg ) 214void QCopBridgePI::sendDesktopMessage( const QString &msg )
215{ 215{
216 QString str = "CALL QPE/Desktop " + msg; 216 QString str = "CALL QPE/Desktop " + msg;
217 send ( str ); 217 send ( str );
218} 218}
219 219
220 220
221void QCopBridgePI::send( const QString& msg ) 221void QCopBridgePI::send( const QString& msg )
222{ 222{
223 QTextStream os( this ); 223 QTextStream os( this );
224 os << msg << endl; 224 os << msg << endl;
225 //qDebug( "sending qcop message: %s", msg.latin1() ); 225 //qDebug( "sending qcop message: %s", msg.latin1() );
226} 226}
227 227
228void QCopBridgePI::read() 228void QCopBridgePI::read()
229{ 229{
230 while ( canReadLine() ) 230 while ( canReadLine() )
231 process( readLine().stripWhiteSpace() ); 231 process( readLine().stripWhiteSpace() );
232} 232}
233 233
234bool QCopBridgePI::checkUser( const QString& user ) 234bool QCopBridgePI::checkUser( const QString& user )
235{ 235{
236 if ( user.isEmpty() ) return FALSE; 236 if ( user.isEmpty() ) return FALSE;
237 237
238 struct passwd *pw; 238 struct passwd *pw;
239 pw = getpwuid( geteuid() ); 239 pw = getpwuid( geteuid() );
240 QString euser = QString::fromLocal8Bit( pw->pw_name ); 240 QString euser = QString::fromLocal8Bit( pw->pw_name );
241 return user == euser; 241 return user == euser;
242} 242}
243 243
244bool QCopBridgePI::checkPassword( const QString& password ) 244bool QCopBridgePI::checkPassword( const QString& password )
245{ 245{
246 // ### HACK for testing on local host 246 // ### HACK for testing on local host
247 return true; 247 return true;
248 248
249 /* 249 /*
250 struct passwd *pw = 0; 250 struct passwd *pw = 0;
251 struct spwd *spw = 0; 251 struct spwd *spw = 0;
252 252
253 pw = getpwuid( geteuid() ); 253 pw = getpwuid( geteuid() );
254 spw = getspnam( pw->pw_name ); 254 spw = getspnam( pw->pw_name );
255 255
256 QString cpwd = QString::fromLocal8Bit( pw->pw_passwd ); 256 QString cpwd = QString::fromLocal8Bit( pw->pw_passwd );
257 if ( cpwd == "x" && spw ) 257 if ( cpwd == "x" && spw )
258 cpwd = QString::fromLocal8Bit( spw->sp_pwdp ); 258 cpwd = QString::fromLocal8Bit( spw->sp_pwdp );
259 259
260 QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) ); 260 QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) );
261 return cpwd == cpassword; 261 return cpwd == cpassword;
262*/ 262*/
263} 263}
264 264
265void QCopBridgePI::process( const QString& message ) 265void QCopBridgePI::process( const QString& message )
266{ 266{
267 //qDebug( "Command: %s", message.latin1() ); 267 //qDebug( "Command: %s", message.latin1() );
268 268
269 // split message using "," as separator 269 // split message using "," as separator
270 QStringList msg = QStringList::split( " ", message ); 270 QStringList msg = QStringList::split( " ", message );
271 if ( msg.isEmpty() ) return; 271 if ( msg.isEmpty() ) return;
272 272
273 // command token 273 // command token
274 QString cmd = msg[0].upper(); 274 QString cmd = msg[0].upper();
275 275
276 // argument token 276 // argument token
277 QString arg; 277 QString arg;
278 if ( msg.count() >= 2 ) 278 if ( msg.count() >= 2 )
279 arg = msg[1]; 279 arg = msg[1];
280 280
281 // we always respond to QUIT, regardless of state 281 // we always respond to QUIT, regardless of state
282 if ( cmd == "QUIT" ) { 282 if ( cmd == "QUIT" ) {
283 send( "211 Have a nice day!" ); 283 send( "211 Have a nice day!" );
284 delete this; 284 delete this;
285 return; 285 return;
286 } 286 }
287 287
288 // connected to client 288 // connected to client
289 if ( Connected == state ) 289 if ( Connected == state )
290 return; 290 return;
291 291
292 // waiting for user name 292 // waiting for user name
293 if ( Wait_USER == state ) { 293 if ( Wait_USER == state ) {
294 294
295 if ( cmd != "USER" || msg.count() < 2 || !checkUser( arg ) ) { 295 if ( cmd != "USER" || msg.count() < 2 || !checkUser( arg ) ) {
296 send( "530 Please login with USER and PASS" ); 296 send( "530 Please login with USER and PASS" );
297 return; 297 return;
298 } 298 }
299 send( "331 User name ok, need password" ); 299 send( "331 User name ok, need password" );
300 state = Wait_PASS; 300 state = Wait_PASS;
301 return; 301 return;
302 } 302 }
303 303
304 // waiting for password 304 // waiting for password
305 if ( Wait_PASS == state ) { 305 if ( Wait_PASS == state ) {
306 306
307 if ( cmd != "PASS" || !checkPassword( arg ) ) { 307 if ( cmd != "PASS" || !checkPassword( arg ) ) {
308 //if ( cmd != "PASS" || msg.count() < 2 || !checkPassword( arg ) ) { 308 //if ( cmd != "PASS" || msg.count() < 2 || !checkPassword( arg ) ) {
309 send( "530 Please login with USER and PASS" ); 309 send( "530 Please login with USER and PASS" );
310 return; 310 return;
311 } 311 }
312 send( "230 User logged in, proceed" ); 312 send( "230 User logged in, proceed" );
313 state = Ready; 313 state = Ready;
314 if ( sendSync ) { 314 if ( sendSync ) {
315 sendDesktopMessage( "startSync()" ); 315 sendDesktopMessage( "startSync()" );
316 sendSync = FALSE; 316 sendSync = FALSE;
317 } 317 }
318 return; 318 return;
319 } 319 }
320 320
321 // noop (NOOP) 321 // noop (NOOP)
322 else if ( cmd == "NOOP" ) { 322 else if ( cmd == "NOOP" ) {
323 connected = TRUE; 323 connected = TRUE;
324 send( "200 Command okay" ); 324 send( "200 Command okay" );
325 } 325 }
326 326
327 // call (CALL) 327 // call (CALL)
328 else if ( cmd == "CALL" ) { 328 else if ( cmd == "CALL" ) {
329 329
330 // example: call QPE/System execute(QString) addressbook 330 // example: call QPE/System execute(QString) addressbook
331 331
332 if ( msg.count() < 3 ) { 332 if ( msg.count() < 3 ) {
333 send( "500 Syntax error, command unrecognized" ); 333 send( "500 Syntax error, command unrecognized" );
334 } 334 }
335 else { 335 else {
336 336
337 QString channel = msg[1]; 337 QString channel = msg[1];
338 QString command = msg[2]; 338 QString command = msg[2];
339 339
340 command.stripWhiteSpace(); 340 command.stripWhiteSpace();
341 341
342 int paren = command.find( "(" ); 342 int paren = command.find( "(" );
343 if ( paren <= 0 ) { 343 if ( paren <= 0 ) {
344 send( "500 Syntax error, command unrecognized" ); 344 send( "500 Syntax error, command unrecognized" );
345 return; 345 return;
346 } 346 }
347 347
348 QString params = command.mid( paren + 1 ); 348 QString params = command.mid( paren + 1 );
349 if ( params[params.length()-1] != ')' ) { 349 if ( params[params.length()-1] != ')' ) {
350 send( "500 Syntax error, command unrecognized" ); 350 send( "500 Syntax error, command unrecognized" );
351 return; 351 return;
352 } 352 }
353 353
354 params.truncate( params.length()-1 ); 354 params.truncate( params.length()-1 );
355 QByteArray buffer; 355 QByteArray buffer;
356 QDataStream ds( buffer, IO_WriteOnly ); 356 QDataStream ds( buffer, IO_WriteOnly );
357 357
358 int msgId = 3; 358 int msgId = 3;
359 359
360 QStringList paramList = QStringList::split( ",", params ); 360 QStringList paramList = QStringList::split( ",", params );
361 if ( paramList.count() > msg.count() - 3 ) { 361 if ( paramList.count() > msg.count() - 3 ) {
362 send( "500 Syntax error, command unrecognized" ); 362 send( "500 Syntax error, command unrecognized" );
363 return; 363 return;
364 } 364 }
365 365
366 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) { 366 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) {
367 367
368 QString arg = msg[msgId]; 368 QString arg = msg[msgId];
369 arg.replace( QRegExp("&0x20;"), " " ); 369 arg.replace( QRegExp("&0x20;"), " " );
370 arg.replace( QRegExp("&amp;"), "&" ); 370 arg.replace( QRegExp("&amp;"), "&" );
371 arg.replace( QRegExp("&0x0d;"), "\n" ); 371 arg.replace( QRegExp("&0x0d;"), "\n" );
372 arg.replace( QRegExp("&0x0a;"), "\r" ); 372 arg.replace( QRegExp("&0x0a;"), "\r" );
373 if ( *it == "QString" ) 373 if ( *it == "QString" )
374 ds << arg; 374 ds << arg;
375 else if ( *it == "QCString" ) 375 else if ( *it == "QCString" )
376 ds << arg.local8Bit(); 376 ds << arg.local8Bit();
377 else if ( *it == "int" ) 377 else if ( *it == "int" )
378 ds << arg.toInt(); 378 ds << arg.toInt();
379 else if ( *it == "bool" ) 379 else if ( *it == "bool" )
380 ds << arg.toInt(); 380 ds << arg.toInt();
381 else { 381 else {
382 send( "500 Syntax error, command unrecognized" ); 382 send( "500 Syntax error, command unrecognized" );
383 return; 383 return;
384 } 384 }
385 msgId++; 385 msgId++;
386 } 386 }
387 387
388 if ( !QCopChannel::isRegistered( channel.latin1() ) ) { 388 if ( !QCopChannel::isRegistered( channel.latin1() ) ) {
389 // send message back about it 389 // send message back about it
390 QString answer = "599 ChannelNotRegistered " + channel; 390 QString answer = "599 ChannelNotRegistered " + channel;
391 send( answer ); 391 send( answer );
392 return; 392 return;
393 } 393 }
394 394
395 if ( paramList.count() ) 395 if ( paramList.count() )
396 QCopChannel::send( channel.latin1(), command.latin1(), buffer ); 396 QCopChannel::send( channel.latin1(), command.latin1(), buffer );
397 else 397 else
398 QCopChannel::send( channel.latin1(), command.latin1() ); 398 QCopChannel::send( channel.latin1(), command.latin1() );
399 399
400 send( "200 Command okay" ); 400 send( "200 Command okay" );
401 } 401 }
402 } 402 }
403 // not implemented 403 // not implemented
404 else 404 else
405 send( "502 Command not implemented" ); 405 send( "502 Command not implemented" );
406} 406}
407 407
408 408
409 409
410void QCopBridgePI::timerEvent( QTimerEvent * ) 410void QCopBridgePI::timerEvent( QTimerEvent * )
411{ 411{
412 if ( connected ) 412 if ( connected )
413 connected = FALSE; 413 connected = FALSE;
414 else 414 else
415 connectionClosed(); 415 connectionClosed();
416} 416}