summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/qcopbridge.cpp4
-rw-r--r--core/launcher/transferserver.cpp5
2 files changed, 7 insertions, 2 deletions
diff --git a/core/launcher/qcopbridge.cpp b/core/launcher/qcopbridge.cpp
index e339dc7..64eb096 100644
--- a/core/launcher/qcopbridge.cpp
+++ b/core/launcher/qcopbridge.cpp
@@ -1,449 +1,451 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#include "qcopbridge.h" 21#include "qcopbridge.h"
22#include "transferserver.h" 22#include "transferserver.h"
23 23
24/* OPIE */ 24/* OPIE */
25#include <opie2/odebug.h> 25#include <opie2/odebug.h>
26#include <opie2/oglobal.h> 26#include <opie2/oglobal.h>
27#ifdef Q_WS_QWS 27#ifdef Q_WS_QWS
28#include <qtopia/qcopenvelope_qws.h> 28#include <qtopia/qcopenvelope_qws.h>
29#endif 29#endif
30#include <qtopia/qpeapplication.h> 30#include <qtopia/qpeapplication.h>
31#include <qtopia/version.h> 31#include <qtopia/version.h>
32using namespace Opie::Core; 32using namespace Opie::Core;
33 33
34/* QT */ 34/* QT */
35#include <qtextstream.h> 35#include <qtextstream.h>
36#include <qtimer.h> 36#include <qtimer.h>
37#ifdef Q_WS_QWS 37#ifdef Q_WS_QWS
38#include <qcopchannel_qws.h> 38#include <qcopchannel_qws.h>
39#endif 39#endif
40 40
41/* STD */ 41/* STD */
42#ifndef _XOPEN_SOURCE 42#ifndef _XOPEN_SOURCE
43#define _XOPEN_SOURCE 43#define _XOPEN_SOURCE
44#endif 44#endif
45#ifndef Q_OS_WIN32 45#ifndef Q_OS_WIN32
46#include <pwd.h> 46#include <pwd.h>
47#include <unistd.h> 47#include <unistd.h>
48#include <fcntl.h>
48#include <sys/types.h> 49#include <sys/types.h>
49#endif 50#endif
50 51
51#if defined(_OS_LINUX_) 52#if defined(_OS_LINUX_)
52#include <shadow.h> 53#include <shadow.h>
53#endif 54#endif
54 55
55const int block_size = 51200; 56const int block_size = 51200;
56 57
57QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent, 58QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent,
58 const char* name ) 59 const char* name )
59 : QServerSocket( port, 1, parent, name ), 60 : QServerSocket( port, 1, parent, name ),
60 desktopChannel( 0 ), 61 desktopChannel( 0 ),
61 cardChannel( 0 ) 62 cardChannel( 0 )
62{ 63{
63 if ( !ok() ) 64 if ( !ok() )
64 owarn << "Failed to bind to port " << port << "" << oendl; 65 owarn << "Failed to bind to port " << port << "" << oendl;
65 else { 66 else {
67 ::fcntl( socket(), F_SETFD, FD_CLOEXEC );
66#ifndef QT_NO_COP 68#ifndef QT_NO_COP
67 desktopChannel = new QCopChannel( "QPE/Desktop", this ); 69 desktopChannel = new QCopChannel( "QPE/Desktop", this );
68 connect( desktopChannel, SIGNAL(received(const QCString&,const QByteArray&)), 70 connect( desktopChannel, SIGNAL(received(const QCString&,const QByteArray&)),
69 this, SLOT(desktopMessage(const QCString&,const QByteArray&)) ); 71 this, SLOT(desktopMessage(const QCString&,const QByteArray&)) );
70 cardChannel = new QCopChannel( "QPE/Card", this ); 72 cardChannel = new QCopChannel( "QPE/Card", this );
71 connect( cardChannel, SIGNAL(received(const QCString&,const QByteArray&)), 73 connect( cardChannel, SIGNAL(received(const QCString&,const QByteArray&)),
72 this, SLOT(desktopMessage(const QCString&,const QByteArray&)) ); 74 this, SLOT(desktopMessage(const QCString&,const QByteArray&)) );
73#endif 75#endif
74 } 76 }
75 sendSync = FALSE; 77 sendSync = FALSE;
76 openConnections.setAutoDelete( TRUE ); 78 openConnections.setAutoDelete( TRUE );
77 authorizeConnections(); 79 authorizeConnections();
78} 80}
79 81
80QCopBridge::~QCopBridge() 82QCopBridge::~QCopBridge()
81{ 83{
82#ifndef QT_NO_COP 84#ifndef QT_NO_COP
83 delete desktopChannel; 85 delete desktopChannel;
84#endif 86#endif
85} 87}
86 88
87void QCopBridge::authorizeConnections() 89void QCopBridge::authorizeConnections()
88{ 90{
89 Config cfg("Security"); 91 Config cfg("Security");
90 cfg.setGroup("SyncMode"); 92 cfg.setGroup("SyncMode");
91 m_mode = Mode(cfg.readNumEntry("Mode", Sharp )); 93 m_mode = Mode(cfg.readNumEntry("Mode", Sharp ));
92 QListIterator<QCopBridgePI> it(openConnections); 94 QListIterator<QCopBridgePI> it(openConnections);
93 while ( it.current() ) { 95 while ( it.current() ) {
94 if ( !it.current()->verifyAuthorised() ) { 96 if ( !it.current()->verifyAuthorised() ) {
95 disconnect ( it.current(), SIGNAL( connectionClosed(QCopBridgePI*) ), this, SLOT( closed(QCopBridgePI*) ) ); 97 disconnect ( it.current(), SIGNAL( connectionClosed(QCopBridgePI*) ), this, SLOT( closed(QCopBridgePI*) ) );
96 openConnections.removeRef( it.current() ); 98 openConnections.removeRef( it.current() );
97 } else 99 } else
98 ++it; 100 ++it;
99 } 101 }
100} 102}
101 103
102void QCopBridge::newConnection( int socket ) 104void QCopBridge::newConnection( int socket )
103{ 105{
104 QCopBridgePI *pi = new QCopBridgePI( socket, this ); 106 QCopBridgePI *pi = new QCopBridgePI( socket, this );
105 openConnections.append( pi ); 107 openConnections.append( pi );
106 connect ( pi, SIGNAL( connectionClosed(QCopBridgePI*) ), this, SLOT( closed(QCopBridgePI*) ) ); 108 connect ( pi, SIGNAL( connectionClosed(QCopBridgePI*) ), this, SLOT( closed(QCopBridgePI*) ) );
107 109
108 /* ### libqtopia merge FIXME */ 110 /* ### libqtopia merge FIXME */
109#if 0 111#if 0
110 QPEApplication::setTempScreenSaverMode( QPEApplication::DisableSuspend ); 112 QPEApplication::setTempScreenSaverMode( QPEApplication::DisableSuspend );
111#endif 113#endif
112#ifndef QT_NO_COP 114#ifndef QT_NO_COP
113 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::DisableSuspend; 115 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::DisableSuspend;
114#endif 116#endif
115 117
116 if ( sendSync ) { 118 if ( sendSync ) {
117 pi ->startSync(); 119 pi ->startSync();
118 sendSync = FALSE; 120 sendSync = FALSE;
119 } 121 }
120} 122}
121 123
122void QCopBridge::closed( QCopBridgePI *pi ) 124void QCopBridge::closed( QCopBridgePI *pi )
123{ 125{
124 emit connectionClosed( pi->peerAddress() ); 126 emit connectionClosed( pi->peerAddress() );
125 openConnections.removeRef( pi ); 127 openConnections.removeRef( pi );
126 if ( openConnections.count() == 0 ) { 128 if ( openConnections.count() == 0 ) {
127 /* ### FIXME libqtopia merge */ 129 /* ### FIXME libqtopia merge */
128#if 0 130#if 0
129 QPEApplication::setTempScreenSaverMode( QPEApplication::Enable ); 131 QPEApplication::setTempScreenSaverMode( QPEApplication::Enable );
130#endif 132#endif
131#ifndef QT_NO_COP 133#ifndef QT_NO_COP
132 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable; 134 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
133#endif 135#endif
134 } 136 }
135} 137}
136 138
137void QCopBridge::closeOpenConnections() 139void QCopBridge::closeOpenConnections()
138{ 140{
139 QCopBridgePI *pi; 141 QCopBridgePI *pi;
140 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) 142 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() )
141 pi->close(); 143 pi->close();
142} 144}
143 145
144 146
145void QCopBridge::desktopMessage( const QCString &command, const QByteArray &data ) 147void QCopBridge::desktopMessage( const QCString &command, const QByteArray &data )
146{ 148{
147 if ( command == "startSync()" ) { 149 if ( command == "startSync()" ) {
148 // we need to buffer it a bit 150 // we need to buffer it a bit
149 sendSync = TRUE; 151 sendSync = TRUE;
150 startTimer( 20000 ); 152 startTimer( 20000 );
151 } 153 }
152 154
153 if ( m_mode & Qtopia1_7 ) { 155 if ( m_mode & Qtopia1_7 ) {
154 // send the command to all open connections 156 // send the command to all open connections
155 QCopBridgePI *pi; 157 QCopBridgePI *pi;
156 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) { 158 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) {
157 pi->sendDesktopMessage( command, data ); 159 pi->sendDesktopMessage( command, data );
158 } 160 }
159 } 161 }
160 if ( ( m_mode & Sharp ) || (m_mode & IntelliSync) ) 162 if ( ( m_mode & Sharp ) || (m_mode & IntelliSync) )
161 sendDesktopMessageOld( command, data ); 163 sendDesktopMessageOld( command, data );
162} 164}
163 165
164#ifndef OPIE_NO_OLD_SYNC_CODE 166#ifndef OPIE_NO_OLD_SYNC_CODE
165/* 167/*
166 * Old compat mode 168 * Old compat mode
167 */ 169 */
168void QCopBridge::sendDesktopMessageOld( const QCString& command, const QByteArray& args) { 170void QCopBridge::sendDesktopMessageOld( const QCString& command, const QByteArray& args) {
169 command.stripWhiteSpace(); 171 command.stripWhiteSpace();
170 172
171 int paren = command.find( "(" ); 173 int paren = command.find( "(" );
172 if ( paren <= 0 ) { 174 if ( paren <= 0 ) {
173 odebug << "DesktopMessage: bad qcop syntax" << oendl; 175 odebug << "DesktopMessage: bad qcop syntax" << oendl;
174 return; 176 return;
175 } 177 }
176 178
177 QString params = command.mid( paren + 1 ); 179 QString params = command.mid( paren + 1 );
178 if ( params[params.length()-1] != ')' ) { 180 if ( params[params.length()-1] != ')' ) {
179 odebug << "DesktopMessage: bad qcop syntax" << oendl; 181 odebug << "DesktopMessage: bad qcop syntax" << oendl;
180 return; 182 return;
181 } 183 }
182 184
183 params.truncate( params.length()-1 ); 185 params.truncate( params.length()-1 );
184 186
185 QStringList paramList = QStringList::split( ",", params ); 187 QStringList paramList = QStringList::split( ",", params );
186 QString data; 188 QString data;
187 if ( paramList.count() ) { 189 if ( paramList.count() ) {
188 QDataStream stream( args, IO_ReadOnly ); 190 QDataStream stream( args, IO_ReadOnly );
189 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) { 191 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) {
190 QString str; 192 QString str;
191 if ( *it == "QString" ) { 193 if ( *it == "QString" ) {
192 stream >> str; 194 stream >> str;
193 } else if ( *it == "QCString" ) { 195 } else if ( *it == "QCString" ) {
194 QCString cstr; 196 QCString cstr;
195 stream >> cstr; 197 stream >> cstr;
196 str = QString::fromLocal8Bit( cstr ); 198 str = QString::fromLocal8Bit( cstr );
197 } else if ( *it == "int" ) { 199 } else if ( *it == "int" ) {
198 int i; 200 int i;
199 stream >> i; 201 stream >> i;
200 str = QString::number( i ); 202 str = QString::number( i );
201 } else if ( *it == "bool" ) { 203 } else if ( *it == "bool" ) {
202 int i; 204 int i;
203 stream >> i; 205 stream >> i;
204 str = QString::number( i ); 206 str = QString::number( i );
205 } else { 207 } else {
206 odebug << " cannot route the argument type " << (*it) << " throught the qcop bridge" << oendl; 208 odebug << " cannot route the argument type " << (*it) << " throught the qcop bridge" << oendl;
207 return; 209 return;
208 } 210 }
209 QString estr; 211 QString estr;
210 for (int i=0; i<(int)str.length(); i++) { 212 for (int i=0; i<(int)str.length(); i++) {
211 QChar ch = str[i]; 213 QChar ch = str[i];
212 if ( ch.row() ) 214 if ( ch.row() )
213 goto quick; 215 goto quick;
214 switch (ch.cell()) { 216 switch (ch.cell()) {
215 case '&': 217 case '&':
216 estr.append( "&amp;" ); 218 estr.append( "&amp;" );
217 break; 219 break;
218 case ' ': 220 case ' ':
219 estr.append( "&0x20;" ); 221 estr.append( "&0x20;" );
220 break; 222 break;
221 case '\n': 223 case '\n':
222 estr.append( "&0x0d;" ); 224 estr.append( "&0x0d;" );
223 break; 225 break;
224 case '\r': 226 case '\r':
225 estr.append( "&0x0a;" ); 227 estr.append( "&0x0a;" );
226 break; 228 break;
227 default: quick: 229 default: quick:
228 estr.append(ch); 230 estr.append(ch);
229 } 231 }
230 } 232 }
231 data += " " + estr; 233 data += " " + estr;
232 } 234 }
233 } 235 }
234 QString sendCommand = QString(command.data()) + data; 236 QString sendCommand = QString(command.data()) + data;
235 237
236 238
237 // send the command to all open connections 239 // send the command to all open connections
238 QCopBridgePI *pi; 240 QCopBridgePI *pi;
239 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) 241 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() )
240 pi->sendDesktopMessage( sendCommand ); 242 pi->sendDesktopMessage( sendCommand );
241 243
242} 244}
243#endif 245#endif
244 246
245 247
246void QCopBridge::timerEvent( QTimerEvent * ) 248void QCopBridge::timerEvent( QTimerEvent * )
247{ 249{
248 sendSync = FALSE; 250 sendSync = FALSE;
249 killTimers(); 251 killTimers();
250} 252}
251 253
252 254
253QCopBridgePI::QCopBridgePI( int socket, QObject *parent, const char* name ) 255QCopBridgePI::QCopBridgePI( int socket, QObject *parent, const char* name )
254 : QSocket( parent, name ) 256 : QSocket( parent, name )
255{ 257{
256 setSocket( socket ); 258 setSocket( socket );
257 259
258 peerport = peerPort(); 260 peerport = peerPort();
259 peeraddress = peerAddress(); 261 peeraddress = peerAddress();
260 262
261#ifndef INSECURE 263#ifndef INSECURE
262 if ( !SyncAuthentication::isAuthorized(peeraddress) ) { 264 if ( !SyncAuthentication::isAuthorized(peeraddress) ) {
263 state = Forbidden; 265 state = Forbidden;
264 close(); 266 close();
265 } else 267 } else
266#endif 268#endif
267 { 269 {
268 state = Connected; 270 state = Connected;
269 connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); 271 connect( this, SIGNAL( readyRead() ), SLOT( read() ) );
270 QString intro="220 Qtopia "; 272 QString intro="220 Qtopia ";
271 intro += QPE_VERSION; intro += ";"; 273 intro += QPE_VERSION; intro += ";";
272 intro += "challenge="; intro += SyncAuthentication::serverId(); intro += ";"; // No tr 274 intro += "challenge="; intro += SyncAuthentication::serverId(); intro += ";"; // No tr
273 intro += "loginname="; intro += SyncAuthentication::loginName(); intro += ";"; 275 intro += "loginname="; intro += SyncAuthentication::loginName(); intro += ";";
274 intro += "displayname="; intro += SyncAuthentication::ownerName(); intro += ";"; 276 intro += "displayname="; intro += SyncAuthentication::ownerName(); intro += ";";
275 send( intro ); 277 send( intro );
276 state = Wait_USER; 278 state = Wait_USER;
277 } 279 }
278 sendSync = FALSE; 280 sendSync = FALSE;
279 connect( this, SIGNAL( connectionClosed() ), SLOT( myConnectionClosed() ) ); 281 connect( this, SIGNAL( connectionClosed() ), SLOT( myConnectionClosed() ) );
280 282
281 // idle timer to close connections when not used anymore 283 // idle timer to close connections when not used anymore
282 timer = new QTimer(this); 284 timer = new QTimer(this);
283 connect( timer, SIGNAL(timeout()), this, SLOT(myConnectionClosed()) ); 285 connect( timer, SIGNAL(timeout()), this, SLOT(myConnectionClosed()) );
284 timer->start( 300000, TRUE ); 286 timer->start( 300000, TRUE );
285} 287}
286 288
287 289
288QCopBridgePI::~QCopBridgePI() 290QCopBridgePI::~QCopBridgePI()
289{ 291{
290} 292}
291 293
292bool QCopBridgePI::verifyAuthorised() 294bool QCopBridgePI::verifyAuthorised()
293{ 295{
294 if ( !SyncAuthentication::isAuthorized(peerAddress()) ) { 296 if ( !SyncAuthentication::isAuthorized(peerAddress()) ) {
295 state = Forbidden; 297 state = Forbidden;
296 return FALSE; 298 return FALSE;
297 } 299 }
298 return TRUE; 300 return TRUE;
299} 301}
300 302
301void QCopBridgePI::myConnectionClosed() 303void QCopBridgePI::myConnectionClosed()
302{ 304{
303 emit connectionClosed( this ); 305 emit connectionClosed( this );
304} 306}
305 307
306void QCopBridgePI::sendDesktopMessage( const QString &msg ) 308void QCopBridgePI::sendDesktopMessage( const QString &msg )
307{ 309{
308 QString str = "CALL QPE/Desktop " + msg; // No tr 310 QString str = "CALL QPE/Desktop " + msg; // No tr
309 send ( str ); 311 send ( str );
310} 312}
311 313
312void QCopBridgePI::sendDesktopMessage( const QCString &msg, const QByteArray& data ) 314void QCopBridgePI::sendDesktopMessage( const QCString &msg, const QByteArray& data )
313{ 315{
314 if ( !isOpen() ) // eg. Forbidden 316 if ( !isOpen() ) // eg. Forbidden
315 return; 317 return;
316 318
317 const char hdr[]="CALLB QPE/Desktop "; 319 const char hdr[]="CALLB QPE/Desktop ";
318 writeBlock(hdr,sizeof(hdr)-1); 320 writeBlock(hdr,sizeof(hdr)-1);
319 writeBlock(msg,msg.length()); 321 writeBlock(msg,msg.length());
320 writeBlock(" ",1); 322 writeBlock(" ",1);
321 QByteArray b64 = OGlobal::encodeBase64(data); 323 QByteArray b64 = OGlobal::encodeBase64(data);
322 writeBlock(b64.data(),b64.size()); 324 writeBlock(b64.data(),b64.size());
323 writeBlock("\r\n",2); 325 writeBlock("\r\n",2);
324 326
325} 327}
326 328
327 329
328void QCopBridgePI::send( const QString& msg ) 330void QCopBridgePI::send( const QString& msg )
329{ 331{
330 if ( !isOpen() ) // eg. Forbidden 332 if ( !isOpen() ) // eg. Forbidden
331 return; 333 return;
332 QTextStream os( this ); 334 QTextStream os( this );
333 os << msg << endl; 335 os << msg << endl;
334 //odebug << "sending qcop message: " << msg << "" << oendl; 336 //odebug << "sending qcop message: " << msg << "" << oendl;
335} 337}
336 338
337void QCopBridgePI::read() 339void QCopBridgePI::read()
338{ 340{
339 while ( canReadLine() ) { 341 while ( canReadLine() ) {
340 timer->start( 300000, TRUE ); 342 timer->start( 300000, TRUE );
341 process( readLine().stripWhiteSpace() ); 343 process( readLine().stripWhiteSpace() );
342 } 344 }
343} 345}
344 346
345void QCopBridgePI::process( const QString& message ) 347void QCopBridgePI::process( const QString& message )
346{ 348{
347 //odebug << "Command: " << message << "" << oendl; 349 //odebug << "Command: " << message << "" << oendl;
348 350
349 // split message using "," as separator 351 // split message using "," as separator
350 QStringList msg = QStringList::split( " ", message ); 352 QStringList msg = QStringList::split( " ", message );
351 if ( msg.isEmpty() ) return; 353 if ( msg.isEmpty() ) return;
352 354
353 // command token 355 // command token
354 QString cmd = msg[0].upper(); 356 QString cmd = msg[0].upper();
355 357
356 // argument token 358 // argument token
357 QString arg; 359 QString arg;
358 if ( msg.count() >= 2 ) 360 if ( msg.count() >= 2 )
359 arg = msg[1]; 361 arg = msg[1];
360 362
361 // we always respond to QUIT, regardless of state 363 // we always respond to QUIT, regardless of state
362 if ( cmd == "QUIT" ) { 364 if ( cmd == "QUIT" ) {
363 send( "211 Have a nice day!" ); // No tr 365 send( "211 Have a nice day!" ); // No tr
364 close(); 366 close();
365 return; 367 return;
366 } 368 }
367 369
368 // connected to client 370 // connected to client
369 if ( Connected == state ) 371 if ( Connected == state )
370 return; 372 return;
371 373
372 // waiting for user name 374 // waiting for user name
373 if ( Wait_USER == state ) { 375 if ( Wait_USER == state ) {
374 376
375 if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) { 377 if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) {
376 send( "530 Please login with USER and PASS" ); // No tr 378 send( "530 Please login with USER and PASS" ); // No tr
377 return; 379 return;
378 } 380 }
379 send( "331 User name ok, need password" ); // No tr 381 send( "331 User name ok, need password" ); // No tr
380 state = Wait_PASS; 382 state = Wait_PASS;
381 return; 383 return;
382 } 384 }
383 385
384 // waiting for password 386 // waiting for password
385 if ( Wait_PASS == state ) { 387 if ( Wait_PASS == state ) {
386 388
387 if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) { 389 if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) {
388 send( "530 Please login with USER and PASS" ); // No tr 390 send( "530 Please login with USER and PASS" ); // No tr
389 return; 391 return;
390 } 392 }
391 send( "230 User logged in, proceed" ); // No tr 393 send( "230 User logged in, proceed" ); // No tr
392 state = Ready; 394 state = Ready;
393 if ( sendSync ) { 395 if ( sendSync ) {
394 sendDesktopMessage( "startSync()" ); 396 sendDesktopMessage( "startSync()" );
395 sendSync = FALSE; 397 sendSync = FALSE;
396 } 398 }
397 return; 399 return;
398 } 400 }
399 401
400 // noop (NOOP) 402 // noop (NOOP)
401 else if ( cmd == "NOOP" ) { 403 else if ( cmd == "NOOP" ) {
402 send( "200 Command okay" ); // No tr 404 send( "200 Command okay" ); // No tr
403 } 405 }
404 406
405 // call (CALL) 407 // call (CALL)
406 else if ( cmd == "CALL" ) { 408 else if ( cmd == "CALL" ) {
407 409
408 // example: call QPE/System execute(QString) addressbook 410 // example: call QPE/System execute(QString) addressbook
409 411
410 if ( msg.count() < 3 ) { 412 if ( msg.count() < 3 ) {
411 send( "500 Syntax error, command unrecognized" ); // No tr 413 send( "500 Syntax error, command unrecognized" ); // No tr
412 } 414 }
413 else { 415 else {
414 416
415 QString channel = msg[1]; 417 QString channel = msg[1];
416 QString command = msg[2]; 418 QString command = msg[2];
417 419
418 command.stripWhiteSpace(); 420 command.stripWhiteSpace();
419 421
420 int paren = command.find( "(" ); 422 int paren = command.find( "(" );
421 if ( paren <= 0 ) { 423 if ( paren <= 0 ) {
422 send( "500 Syntax error, command unrecognized" ); // No tr 424 send( "500 Syntax error, command unrecognized" ); // No tr
423 return; 425 return;
424 } 426 }
425 427
426 QString params = command.mid( paren + 1 ); 428 QString params = command.mid( paren + 1 );
427 if ( params[(int)params.length()-1] != ')' ) { 429 if ( params[(int)params.length()-1] != ')' ) {
428 send( "500 Syntax error, command unrecognized" ); // No tr 430 send( "500 Syntax error, command unrecognized" ); // No tr
429 return; 431 return;
430 } 432 }
431 433
432 params.truncate( params.length()-1 ); 434 params.truncate( params.length()-1 );
433 QByteArray buffer; 435 QByteArray buffer;
434 QDataStream ds( buffer, IO_WriteOnly ); 436 QDataStream ds( buffer, IO_WriteOnly );
435 437
436 int msgId = 3; 438 int msgId = 3;
437 439
438 QStringList paramList = QStringList::split( ",", params ); 440 QStringList paramList = QStringList::split( ",", params );
439 if ( paramList.count() > msg.count() - 3 ) { 441 if ( paramList.count() > msg.count() - 3 ) {
440 send( "500 Syntax error, command unrecognized" ); // No tr 442 send( "500 Syntax error, command unrecognized" ); // No tr
441 return; 443 return;
442 } 444 }
443 445
444 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) { 446 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) {
445 447
446 QString arg = msg[msgId]; 448 QString arg = msg[msgId];
447 arg.replace( QRegExp("&0x20;"), " " ); 449 arg.replace( QRegExp("&0x20;"), " " );
448 arg.replace( QRegExp("&amp;"), "&" ); 450 arg.replace( QRegExp("&amp;"), "&" );
449 arg.replace( QRegExp("&0x0d;"), "\n" ); 451 arg.replace( QRegExp("&0x0d;"), "\n" );
diff --git a/core/launcher/transferserver.cpp b/core/launcher/transferserver.cpp
index 2b2e435..a219c0f 100644
--- a/core/launcher/transferserver.cpp
+++ b/core/launcher/transferserver.cpp
@@ -1,442 +1,445 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20#include "transferserver.h" 20#include "transferserver.h"
21 21
22/* OPIE */ 22/* OPIE */
23#include <opie2/odebug.h> 23#include <opie2/odebug.h>
24#include <opie2/oglobal.h> 24#include <opie2/oglobal.h>
25#include <qtopia/qprocess.h> 25#include <qtopia/qprocess.h>
26#include <qtopia/process.h> 26#include <qtopia/process.h>
27#include <qtopia/private/contact.h> 27#include <qtopia/private/contact.h>
28#include <qtopia/version.h> 28#include <qtopia/version.h>
29#ifdef Q_WS_QWS 29#ifdef Q_WS_QWS
30#include <qtopia/qcopenvelope_qws.h> 30#include <qtopia/qcopenvelope_qws.h>
31#endif 31#endif
32using namespace Opie::Core; 32using namespace Opie::Core;
33 33
34/* QT */ 34/* QT */
35#include <qtextstream.h> 35#include <qtextstream.h>
36#include <qmessagebox.h> 36#include <qmessagebox.h>
37 37
38/* STD */ 38/* STD */
39#include <pwd.h> 39#include <pwd.h>
40#include <sys/types.h> 40#include <sys/types.h>
41#include <unistd.h> 41#include <unistd.h>
42#include <fcntl.h>
42#include <stdlib.h> 43#include <stdlib.h>
43#include <time.h> 44#include <time.h>
44 45
45#ifndef Q_OS_MACX 46#ifndef Q_OS_MACX
46#include <shadow.h> 47#include <shadow.h>
47#include <crypt.h> 48#include <crypt.h>
48#endif /* Q_OS_MACX */ 49#endif /* Q_OS_MACX */
49 50
50const int block_size = 51200; 51const int block_size = 51200;
51 52
52TransferServer::TransferServer( Q_UINT16 port, QObject *parent, 53TransferServer::TransferServer( Q_UINT16 port, QObject *parent,
53 const char* name) 54 const char* name)
54 : QServerSocket( port, 1, parent, name ) 55 : QServerSocket( port, 1, parent, name )
55{ 56{
56 connections.setAutoDelete( TRUE ); 57 connections.setAutoDelete( TRUE );
57 if ( !ok() ) 58 if ( !ok() )
58 owarn << "Failed to bind to port " << port << "" << oendl; 59 owarn << "Failed to bind to port " << port << "" << oendl;
60 else
61 ::fcntl( socket(), F_SETFD, FD_CLOEXEC );
59} 62}
60 63
61void TransferServer::authorizeConnections() 64void TransferServer::authorizeConnections()
62{ 65{
63 QListIterator<ServerPI> it(connections); 66 QListIterator<ServerPI> it(connections);
64 while ( it.current() ) { 67 while ( it.current() ) {
65 if ( !it.current()->verifyAuthorised() ) { 68 if ( !it.current()->verifyAuthorised() ) {
66 disconnect( it.current(), SIGNAL(connectionClosed(ServerPI*)), this, SLOT( closed(ServerPI*)) ); 69 disconnect( it.current(), SIGNAL(connectionClosed(ServerPI*)), this, SLOT( closed(ServerPI*)) );
67 connections.removeRef( it.current() ); 70 connections.removeRef( it.current() );
68 } else 71 } else
69 ++it; 72 ++it;
70 } 73 }
71} 74}
72 75
73void TransferServer::closed(ServerPI *item) 76void TransferServer::closed(ServerPI *item)
74{ 77{
75 connections.removeRef(item); 78 connections.removeRef(item);
76} 79}
77 80
78TransferServer::~TransferServer() 81TransferServer::~TransferServer()
79{ 82{
80} 83}
81 84
82void TransferServer::newConnection( int socket ) 85void TransferServer::newConnection( int socket )
83{ 86{
84 ServerPI *ptr = new ServerPI( socket, this ); 87 ServerPI *ptr = new ServerPI( socket, this );
85 connect( ptr, SIGNAL(connectionClosed(ServerPI*)), this, SLOT( closed(ServerPI*)) ); 88 connect( ptr, SIGNAL(connectionClosed(ServerPI*)), this, SLOT( closed(ServerPI*)) );
86 connections.append( ptr ); 89 connections.append( ptr );
87} 90}
88 91
89QString SyncAuthentication::serverId() 92QString SyncAuthentication::serverId()
90{ 93{
91 Config cfg("Security"); 94 Config cfg("Security");
92 cfg.setGroup("Sync"); 95 cfg.setGroup("Sync");
93 QString r = cfg.readEntry("serverid"); 96 QString r = cfg.readEntry("serverid");
94 97
95 if ( r.isEmpty() ) { 98 if ( r.isEmpty() ) {
96 r = OGlobal::generateUuid(); 99 r = OGlobal::generateUuid();
97 cfg.writeEntry("serverid", r ); 100 cfg.writeEntry("serverid", r );
98 } 101 }
99 return r; 102 return r;
100} 103}
101 104
102QString SyncAuthentication::ownerName() 105QString SyncAuthentication::ownerName()
103{ 106{
104 QString vfilename = Global::applicationFileName("addressbook", 107 QString vfilename = Global::applicationFileName("addressbook",
105 "businesscard.vcf"); 108 "businesscard.vcf");
106 if (QFile::exists(vfilename)) { 109 if (QFile::exists(vfilename)) {
107 Contact c; 110 Contact c;
108 c = Contact::readVCard( vfilename )[0]; 111 c = Contact::readVCard( vfilename )[0];
109 return c.fullName(); 112 return c.fullName();
110 } 113 }
111 114
112 return QString::null; 115 return QString::null;
113} 116}
114 117
115QString SyncAuthentication::loginName() 118QString SyncAuthentication::loginName()
116{ 119{
117 struct passwd *pw = 0L; 120 struct passwd *pw = 0L;
118#ifndef Q_OS_WIN32 121#ifndef Q_OS_WIN32
119 pw = getpwuid( geteuid() ); 122 pw = getpwuid( geteuid() );
120 return QString::fromLocal8Bit( pw->pw_name ); 123 return QString::fromLocal8Bit( pw->pw_name );
121#else 124#else
122 //### revise 125 //### revise
123 return QString(); 126 return QString();
124#endif 127#endif
125} 128}
126 129
127int SyncAuthentication::isAuthorized(QHostAddress peeraddress) 130int SyncAuthentication::isAuthorized(QHostAddress peeraddress)
128{ 131{
129 Config cfg("Security"); 132 Config cfg("Security");
130 cfg.setGroup("Sync"); 133 cfg.setGroup("Sync");
131 // QString allowedstr = cfg.readEntry("auth_peer","192.168.1.0"); 134 // QString allowedstr = cfg.readEntry("auth_peer","192.168.1.0");
132 uint auth_peer = cfg.readNumEntry("auth_peer", 0xc0a80100); 135 uint auth_peer = cfg.readNumEntry("auth_peer", 0xc0a80100);
133 136
134 // QHostAddress allowed; 137 // QHostAddress allowed;
135 // allowed.setAddress(allowedstr); 138 // allowed.setAddress(allowedstr);
136 // uint auth_peer = allowed.ip4Addr(); 139 // uint auth_peer = allowed.ip4Addr();
137 uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits", 24); 140 uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits", 24);
138 uint mask = auth_peer_bits >= 32 // shifting by 32 is not defined 141 uint mask = auth_peer_bits >= 32 // shifting by 32 is not defined
139 ? 0xffffffff : (((1 << auth_peer_bits) - 1) << (32 - auth_peer_bits)); 142 ? 0xffffffff : (((1 << auth_peer_bits) - 1) << (32 - auth_peer_bits));
140 143
141 return (peeraddress.ip4Addr() & mask) == auth_peer; 144 return (peeraddress.ip4Addr() & mask) == auth_peer;
142} 145}
143 146
144bool SyncAuthentication::checkUser( const QString& user ) 147bool SyncAuthentication::checkUser( const QString& user )
145{ 148{
146 if ( user.isEmpty() ) return FALSE; 149 if ( user.isEmpty() ) return FALSE;
147 QString euser = loginName(); 150 QString euser = loginName();
148 return user == euser; 151 return user == euser;
149} 152}
150 153
151bool SyncAuthentication::checkPassword( const QString& password ) 154bool SyncAuthentication::checkPassword( const QString& password )
152{ 155{
153#ifdef ALLOW_UNIX_USER_FTP 156#ifdef ALLOW_UNIX_USER_FTP
154 // First, check system password... 157 // First, check system password...
155 158
156 struct passwd *pw = 0; 159 struct passwd *pw = 0;
157 struct spwd *spw = 0; 160 struct spwd *spw = 0;
158 161
159 pw = getpwuid( geteuid() ); 162 pw = getpwuid( geteuid() );
160 spw = getspnam( pw->pw_name ); 163 spw = getspnam( pw->pw_name );
161 164
162 QString cpwd = QString::fromLocal8Bit( pw->pw_passwd ); 165 QString cpwd = QString::fromLocal8Bit( pw->pw_passwd );
163 if ( cpwd == "x" && spw ) 166 if ( cpwd == "x" && spw )
164 cpwd = QString::fromLocal8Bit( spw->sp_pwdp ); 167 cpwd = QString::fromLocal8Bit( spw->sp_pwdp );
165 168
166 // Note: some systems use more than crypt for passwords. 169 // Note: some systems use more than crypt for passwords.
167 QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) ); 170 QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) );
168 if ( cpwd == cpassword ) 171 if ( cpwd == cpassword )
169 return TRUE; 172 return TRUE;
170#endif 173#endif
171 174
172 static int lastdenial=0; 175 static int lastdenial=0;
173 static int denials=0; 176 static int denials=0;
174 int now = time(0); 177 int now = time(0);
175 178
176 Config cfg("Security"); 179 Config cfg("Security");
177 cfg.setGroup("SyncMode"); 180 cfg.setGroup("SyncMode");
178 int mode = cfg.readNumEntry("Mode", 0x02 ); 181 int mode = cfg.readNumEntry("Mode", 0x02 );
179 182
180 //No pass word needed if the user really needs it 183 //No pass word needed if the user really needs it
181 if (mode & 0x04) { 184 if (mode & 0x04) {
182 QMessageBox unauth( 185 QMessageBox unauth(
183 tr("Sync Connection"), 186 tr("Sync Connection"),
184 tr("<qt><p>An unauthorized system is requesting access to this device." 187 tr("<qt><p>An unauthorized system is requesting access to this device."
185 "<p>You chose IntelliSync so you may I allow or deny this connection.</qt>" ), 188 "<p>You chose IntelliSync so you may I allow or deny this connection.</qt>" ),
186 QMessageBox::Warning, 189 QMessageBox::Warning,
187 QMessageBox::Ok, QMessageBox::Cancel|QMessageBox::Default, QMessageBox::NoButton, 190 QMessageBox::Ok, QMessageBox::Cancel|QMessageBox::Default, QMessageBox::NoButton,
188 0, QString::null, TRUE, WStyle_StaysOnTop); 191 0, QString::null, TRUE, WStyle_StaysOnTop);
189 unauth.setButtonText(QMessageBox::Ok, tr("Allow" ) ); 192 unauth.setButtonText(QMessageBox::Ok, tr("Allow" ) );
190 unauth.setButtonText(QMessageBox::Cancel, tr("Deny")); 193 unauth.setButtonText(QMessageBox::Cancel, tr("Deny"));
191 switch( unauth.exec() ) { 194 switch( unauth.exec() ) {
192 case QMessageBox::Ok: 195 case QMessageBox::Ok:
193 return TRUE; 196 return TRUE;
194 break; 197 break;
195 case QMessageBox::Cancel: 198 case QMessageBox::Cancel:
196 default: 199 default:
197 denials++; 200 denials++;
198 lastdenial=now; 201 lastdenial=now;
199 return FALSE; 202 return FALSE;
200 } 203 }
201 } 204 }
202 205
203 // Detect old Qtopia Desktop (no password) and fail 206 // Detect old Qtopia Desktop (no password) and fail
204 if ( password.isEmpty() ) { 207 if ( password.isEmpty() ) {
205 if ( denials < 3 || now > lastdenial+600 ) { 208 if ( denials < 3 || now > lastdenial+600 ) {
206 QMessageBox unauth( 209 QMessageBox unauth(
207 tr("Sync Connection"), 210 tr("Sync Connection"),
208 tr("<p>An unauthorized system is requesting access to this device." 211 tr("<p>An unauthorized system is requesting access to this device."
209 "<p>If you are using a version of Qtopia Desktop older than 1.5.1, " 212 "<p>If you are using a version of Qtopia Desktop older than 1.5.1, "
210 "please upgrade or change the security setting to use IntelliSync." ), 213 "please upgrade or change the security setting to use IntelliSync." ),
211 QMessageBox::Warning, 214 QMessageBox::Warning,
212 QMessageBox::Cancel, QMessageBox::NoButton, QMessageBox::NoButton, 215 QMessageBox::Cancel, QMessageBox::NoButton, QMessageBox::NoButton,
213 0, QString::null, TRUE, WStyle_StaysOnTop); 216 0, QString::null, TRUE, WStyle_StaysOnTop);
214 unauth.setButtonText(QMessageBox::Cancel, tr("Deny")); 217 unauth.setButtonText(QMessageBox::Cancel, tr("Deny"));
215 unauth.exec(); 218 unauth.exec();
216 219
217 denials++; 220 denials++;
218 lastdenial=now; 221 lastdenial=now;
219 } 222 }
220 return FALSE; 223 return FALSE;
221 224
222 } 225 }
223 226
224 // Second, check sync password... 227 // Second, check sync password...
225 228
226 static int lock=0; 229 static int lock=0;
227 if ( lock ) return FALSE; 230 if ( lock ) return FALSE;
228 231
229 ++lock; 232 ++lock;
230 233
231 /* 234 /*
232 * we need to support old Sync software and QtopiaDesktop 235 * we need to support old Sync software and QtopiaDesktop
233 */ 236 */
234 if ( password.left(6) == "Qtopia" || password.left(6) == "rootme" ) { 237 if ( password.left(6) == "Qtopia" || password.left(6) == "rootme" ) {
235 cfg.setGroup("Sync"); 238 cfg.setGroup("Sync");
236 QStringList pwds = cfg.readListEntry("Passwords",' '); 239 QStringList pwds = cfg.readListEntry("Passwords",' ');
237 for (QStringList::ConstIterator it=pwds.begin(); it!=pwds.end(); ++it) { 240 for (QStringList::ConstIterator it=pwds.begin(); it!=pwds.end(); ++it) {
238#ifndef Q_OS_WIN32 241#ifndef Q_OS_WIN32
239 QString cpassword = QString::fromLocal8Bit( 242 QString cpassword = QString::fromLocal8Bit(
240 crypt( password.mid(8).local8Bit(), (*it).left(2).latin1() ) ); 243 crypt( password.mid(8).local8Bit(), (*it).left(2).latin1() ) );
241#else 244#else
242 // ### revise 245 // ### revise
243 QString cpassword(""); 246 QString cpassword("");
244#endif 247#endif
245 if ( *it == cpassword ) { 248 if ( *it == cpassword ) {
246 lock--; 249 lock--;
247 return TRUE; 250 return TRUE;
248 } 251 }
249 } 252 }
250 253
251 // Unrecognized system. Be careful... 254 // Unrecognized system. Be careful...
252 QMessageBox unrecbox( 255 QMessageBox unrecbox(
253 tr("Sync Connection"), 256 tr("Sync Connection"),
254 tr( "<p>An unrecognized system is requesting access to this device." 257 tr( "<p>An unrecognized system is requesting access to this device."
255 "<p>If you have just initiated a Sync for the first time, this is normal."), 258 "<p>If you have just initiated a Sync for the first time, this is normal."),
256 QMessageBox::Warning, 259 QMessageBox::Warning,
257 QMessageBox::Cancel, QMessageBox::Yes, QMessageBox::NoButton, 260 QMessageBox::Cancel, QMessageBox::Yes, QMessageBox::NoButton,
258 0, QString::null, TRUE, WStyle_StaysOnTop); 261 0, QString::null, TRUE, WStyle_StaysOnTop);
259 unrecbox.setButtonText(QMessageBox::Cancel, tr("Deny")); 262 unrecbox.setButtonText(QMessageBox::Cancel, tr("Deny"));
260 unrecbox.setButtonText(QMessageBox::Yes, tr("Allow")); 263 unrecbox.setButtonText(QMessageBox::Yes, tr("Allow"));
261 264
262 if ( (denials > 2 && now < lastdenial+600) 265 if ( (denials > 2 && now < lastdenial+600)
263 || unrecbox.exec() != QMessageBox::Yes) 266 || unrecbox.exec() != QMessageBox::Yes)
264 { 267 {
265 denials++; 268 denials++;
266 lastdenial=now; 269 lastdenial=now;
267 lock--; 270 lock--;
268 return FALSE; 271 return FALSE;
269 } else { 272 } else {
270 const char salty[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/."; 273 const char salty[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/.";
271 char salt[2]; 274 char salt[2];
272 salt[0]= salty[rand() % (sizeof(salty)-1)]; 275 salt[0]= salty[rand() % (sizeof(salty)-1)];
273 salt[1]= salty[rand() % (sizeof(salty)-1)]; 276 salt[1]= salty[rand() % (sizeof(salty)-1)];
274#ifndef Q_OS_WIN32 277#ifndef Q_OS_WIN32
275 QString cpassword = QString::fromLocal8Bit( 278 QString cpassword = QString::fromLocal8Bit(
276 crypt( password.mid(8).local8Bit(), salt ) ); 279 crypt( password.mid(8).local8Bit(), salt ) );
277#else 280#else
278 //### revise 281 //### revise
279 QString cpassword(""); 282 QString cpassword("");
280#endif 283#endif
281 denials=0; 284 denials=0;
282 pwds.prepend(cpassword); 285 pwds.prepend(cpassword);
283 cfg.writeEntry("Passwords",pwds,' '); 286 cfg.writeEntry("Passwords",pwds,' ');
284 lock--; 287 lock--;
285 return TRUE; 288 return TRUE;
286 } 289 }
287 } 290 }
288 lock--; 291 lock--;
289 292
290 return FALSE; 293 return FALSE;
291} 294}
292 295
293 296
294ServerPI::ServerPI( int socket, QObject *parent, const char* name ) 297ServerPI::ServerPI( int socket, QObject *parent, const char* name )
295 : QSocket( parent, name ) , dtp( 0 ), serversocket( 0 ), waitsocket( 0 ), 298 : QSocket( parent, name ) , dtp( 0 ), serversocket( 0 ), waitsocket( 0 ),
296 storFileSize(-1) 299 storFileSize(-1)
297{ 300{
298 state = Connected; 301 state = Connected;
299 302
300 setSocket( socket ); 303 setSocket( socket );
301 304
302 peerport = peerPort(); 305 peerport = peerPort();
303 peeraddress = peerAddress(); 306 peeraddress = peerAddress();
304 307
305#ifndef INSECURE 308#ifndef INSECURE
306 if ( !SyncAuthentication::isAuthorized(peeraddress) ) { 309 if ( !SyncAuthentication::isAuthorized(peeraddress) ) {
307 state = Forbidden; 310 state = Forbidden;
308 startTimer( 0 ); 311 startTimer( 0 );
309 } else 312 } else
310#endif 313#endif
311 { 314 {
312 connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); 315 connect( this, SIGNAL( readyRead() ), SLOT( read() ) );
313 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); 316 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
314 317
315 passiv = FALSE; 318 passiv = FALSE;
316 for( int i = 0; i < 4; i++ ) 319 for( int i = 0; i < 4; i++ )
317 wait[i] = FALSE; 320 wait[i] = FALSE;
318 321
319 send( "220 Qtopia " QPE_VERSION " FTP Server" ); // No tr 322 send( "220 Qtopia " QPE_VERSION " FTP Server" ); // No tr
320 state = Wait_USER; 323 state = Wait_USER;
321 324
322 dtp = new ServerDTP( this ); 325 dtp = new ServerDTP( this );
323 connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) ); 326 connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) );
324 connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) ); 327 connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) );
325 connect( dtp, SIGNAL( error(int) ), SLOT( dtpError(int) ) ); 328 connect( dtp, SIGNAL( error(int) ), SLOT( dtpError(int) ) );
326 329
327 330
328 directory = QDir::currentDirPath(); 331 directory = QDir::currentDirPath();
329 332
330 static int p = 1024; 333 static int p = 1024;
331 334
332 while ( !serversocket || !serversocket->ok() ) { 335 while ( !serversocket || !serversocket->ok() ) {
333 delete serversocket; 336 delete serversocket;
334 serversocket = new ServerSocket( ++p, this ); 337 serversocket = new ServerSocket( ++p, this );
335 } 338 }
336 connect( serversocket, SIGNAL( newIncomming(int) ), 339 connect( serversocket, SIGNAL( newIncomming(int) ),
337 SLOT( newConnection(int) ) ); 340 SLOT( newConnection(int) ) );
338 } 341 }
339} 342}
340 343
341ServerPI::~ServerPI() 344ServerPI::~ServerPI()
342{ 345{
343 close(); 346 close();
344 347
345 if ( dtp ) 348 if ( dtp )
346 dtp->close(); 349 dtp->close();
347 delete dtp; 350 delete dtp;
348 delete serversocket; 351 delete serversocket;
349} 352}
350 353
351bool ServerPI::verifyAuthorised() 354bool ServerPI::verifyAuthorised()
352{ 355{
353 if ( !SyncAuthentication::isAuthorized(peerAddress()) ) { 356 if ( !SyncAuthentication::isAuthorized(peerAddress()) ) {
354 state = Forbidden; 357 state = Forbidden;
355 return FALSE; 358 return FALSE;
356 } 359 }
357 return TRUE; 360 return TRUE;
358} 361}
359 362
360void ServerPI::connectionClosed() 363void ServerPI::connectionClosed()
361{ 364{
362 // odebug << "Debug: Connection closed" << oendl; 365 // odebug << "Debug: Connection closed" << oendl;
363 emit connectionClosed(this); 366 emit connectionClosed(this);
364} 367}
365 368
366void ServerPI::send( const QString& msg ) 369void ServerPI::send( const QString& msg )
367{ 370{
368 QTextStream os( this ); 371 QTextStream os( this );
369 os << msg << endl; 372 os << msg << endl;
370 //odebug << "Reply: " << msg << "" << oendl; 373 //odebug << "Reply: " << msg << "" << oendl;
371} 374}
372 375
373void ServerPI::read() 376void ServerPI::read()
374{ 377{
375 while ( canReadLine() ) 378 while ( canReadLine() )
376 process( readLine().stripWhiteSpace() ); 379 process( readLine().stripWhiteSpace() );
377} 380}
378 381
379bool ServerPI::checkReadFile( const QString& file ) 382bool ServerPI::checkReadFile( const QString& file )
380{ 383{
381 QString filename; 384 QString filename;
382 385
383 if ( file.length() == 1 && file[0] == "/" ) 386 if ( file.length() == 1 && file[0] == "/" )
384 filename = file; 387 filename = file;
385 else if ( file[0] != "/" ) 388 else if ( file[0] != "/" )
386 filename = directory.path() + "/" + file; 389 filename = directory.path() + "/" + file;
387 else 390 else
388 filename = file; 391 filename = file;
389 392
390 QFileInfo fi( filename ); 393 QFileInfo fi( filename );
391 return ( fi.exists() && fi.isReadable() ); 394 return ( fi.exists() && fi.isReadable() );
392} 395}
393 396
394bool ServerPI::checkWriteFile( const QString& file ) 397bool ServerPI::checkWriteFile( const QString& file )
395{ 398{
396 QString filename; 399 QString filename;
397 400
398 if ( file[0] != "/" ) 401 if ( file[0] != "/" )
399 filename = directory.path() + "/" + file; 402 filename = directory.path() + "/" + file;
400 else 403 else
401 filename = file; 404 filename = file;
402 405
403 QFileInfo fi( filename ); 406 QFileInfo fi( filename );
404 407
405 if ( fi.exists() ) 408 if ( fi.exists() )
406 if ( !QFile( filename ).remove() ) 409 if ( !QFile( filename ).remove() )
407 return FALSE; 410 return FALSE;
408 return TRUE; 411 return TRUE;
409} 412}
410 413
411void ServerPI::process( const QString& message ) 414void ServerPI::process( const QString& message )
412{ 415{
413 //odebug << "Command: " << message << "" << oendl; 416 //odebug << "Command: " << message << "" << oendl;
414 417
415 // split message using "," as separator 418 // split message using "," as separator
416 QStringList msg = QStringList::split( " ", message ); 419 QStringList msg = QStringList::split( " ", message );
417 if ( msg.isEmpty() ) return; 420 if ( msg.isEmpty() ) return;
418 421
419 // command token 422 // command token
420 QString cmd = msg[0].upper(); 423 QString cmd = msg[0].upper();
421 424
422 // argument token 425 // argument token
423 QString arg; 426 QString arg;
424 if ( msg.count() >= 2 ) 427 if ( msg.count() >= 2 )
425 arg = msg[1]; 428 arg = msg[1];
426 429
427 // full argument string 430 // full argument string
428 QString args; 431 QString args;
429 if ( msg.count() >= 2 ) { 432 if ( msg.count() >= 2 ) {
430 QStringList copy( msg ); 433 QStringList copy( msg );
431 // FIXME: for Qt3 434 // FIXME: for Qt3
432 // copy.pop_front() 435 // copy.pop_front()
433 copy.remove( copy.begin() ); 436 copy.remove( copy.begin() );
434 args = copy.join( " " ); 437 args = copy.join( " " );
435 } 438 }
436 439
437 //odebug << "args: " << args << "" << oendl; 440 //odebug << "args: " << args << "" << oendl;
438 441
439 // we always respond to QUIT, regardless of state 442 // we always respond to QUIT, regardless of state
440 if ( cmd == "QUIT" ) { 443 if ( cmd == "QUIT" ) {
441 send( "211 Good bye!" ); // No tr 444 send( "211 Good bye!" ); // No tr
442 close(); 445 close();