summaryrefslogtreecommitdiff
authorzecke <zecke>2002-07-12 13:51:37 (UTC)
committer zecke <zecke>2002-07-12 13:51:37 (UTC)
commit716211b5e06bb25145cfbcf62a11a7c52c79dde5 (patch) (unidiff)
tree595c4c15cb0ca31f2579be42ee029c1c30454b9c
parent7c12000481b535ce54951ef8a53b439814f8fcd6 (diff)
downloadopie-716211b5e06bb25145cfbcf62a11a7c52c79dde5.zip
opie-716211b5e06bb25145cfbcf62a11a7c52c79dde5.tar.gz
opie-716211b5e06bb25145cfbcf62a11a7c52c79dde5.tar.bz2
Security fix by trolltech
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/desktop.cpp4
-rw-r--r--core/launcher/launcher.pro2
-rw-r--r--core/launcher/qcopbridge.cpp424
-rw-r--r--core/launcher/qcopbridge.h7
-rw-r--r--core/launcher/transferserver.cpp213
-rw-r--r--core/launcher/transferserver.h23
6 files changed, 392 insertions, 281 deletions
diff --git a/core/launcher/desktop.cpp b/core/launcher/desktop.cpp
index 24dce73..541b4be 100644
--- a/core/launcher/desktop.cpp
+++ b/core/launcher/desktop.cpp
@@ -537,66 +537,66 @@ void Desktop::raiseMenu()
537 QCopEnvelope e("QPE/System","execute(QString)"); 537 QCopEnvelope e("QPE/System","execute(QString)");
538 e << tempItem; 538 e << tempItem;
539 } 539 }
540} 540}
541 541
542void Desktop::raiseEmail() 542void Desktop::raiseEmail()
543{ 543{
544 Config cfg("qpe"); //F13, 'Mail' 544 Config cfg("qpe"); //F13, 'Mail'
545 cfg.setGroup("AppsKey"); 545 cfg.setGroup("AppsKey");
546 QString tempItem; 546 QString tempItem;
547 tempItem = cfg.readEntry("RightEnd","Mail"); 547 tempItem = cfg.readEntry("RightEnd","Mail");
548 if(tempItem == "Mail" || tempItem == "qtmail" || tempItem.isEmpty()) executeOrModify("Applications/qtmail.desktop"); 548 if(tempItem == "Mail" || tempItem == "qtmail" || tempItem.isEmpty()) executeOrModify("Applications/qtmail.desktop");
549 else { 549 else {
550 QCopEnvelope e("QPE/System","execute(QString)"); 550 QCopEnvelope e("QPE/System","execute(QString)");
551 e << tempItem; 551 e << tempItem;
552 } 552 }
553} 553}
554 554
555// autoStarts apps on resume and start 555// autoStarts apps on resume and start
556void Desktop::execAutoStart() { 556void Desktop::execAutoStart() {
557 QString appName; 557 QString appName;
558 int delay; 558 int delay;
559 QDateTime now = QDateTime::currentDateTime(); 559 QDateTime now = QDateTime::currentDateTime();
560 Config cfg( "autostart" ); 560 Config cfg( "autostart" );
561 cfg.setGroup( "AutoStart" ); 561 cfg.setGroup( "AutoStart" );
562 appName = cfg.readEntry("Apps", ""); 562 appName = cfg.readEntry("Apps", "");
563 delay = (cfg.readEntry("Delay", "0" )).toInt(); 563 delay = (cfg.readEntry("Delay", "0" )).toInt();
564 // If the time between suspend and resume was longer then the 564 // If the time between suspend and resume was longer then the
565 // value saved as delay, start the app 565 // value saved as delay, start the app
566 if ( suspendTime.secsTo(now) >= (delay*60) ) { 566 if ( suspendTime.secsTo(now) >= (delay*60) ) {
567 QCopEnvelope e("QPE/System", "execute(QString)"); 567 QCopEnvelope e("QPE/System", "execute(QString)");
568 e << QString(appName); 568 e << QString(appName);
569 } else { 569 } //else {
570 } 570 //}
571} 571}
572 572
573#if defined(QPE_HAVE_TOGGLELIGHT) 573#if defined(QPE_HAVE_TOGGLELIGHT)
574#include <qpe/config.h> 574#include <qpe/config.h>
575 575
576#include <sys/ioctl.h> 576#include <sys/ioctl.h>
577#include <sys/types.h> 577#include <sys/types.h>
578#include <fcntl.h> 578#include <fcntl.h>
579#include <unistd.h> 579#include <unistd.h>
580#include <errno.h> 580#include <errno.h>
581#include <linux/ioctl.h> 581#include <linux/ioctl.h>
582#include <time.h> 582#include <time.h>
583#endif 583#endif
584 584
585static bool blanked=FALSE; 585static bool blanked=FALSE;
586 586
587static void blankScreen() 587static void blankScreen()
588{ 588{
589 if ( !qt_screen ) return; 589 if ( !qt_screen ) return;
590 /* Should use a big black window instead. 590 /* Should use a big black window instead.
591 QGfx* g = qt_screen->screenGfx(); 591 QGfx* g = qt_screen->screenGfx();
592 g->fillRect(0,0,qt_screen->width(),qt_screen->height()); 592 g->fillRect(0,0,qt_screen->width(),qt_screen->height());
593 delete g; 593 delete g;
594 */ 594 */
595 blanked = TRUE; 595 blanked = TRUE;
596} 596}
597 597
598static void darkScreen() 598static void darkScreen()
599{ 599{
600 extern void qpe_setBacklight(int); 600 extern void qpe_setBacklight(int);
601 qpe_setBacklight(0); // force off 601 qpe_setBacklight(0); // force off
602} 602}
diff --git a/core/launcher/launcher.pro b/core/launcher/launcher.pro
index ccf8231..169edc1 100644
--- a/core/launcher/launcher.pro
+++ b/core/launcher/launcher.pro
@@ -70,48 +70,48 @@ SOURCES = background.cpp \
70 $(OPIEDIR)/rsync/checksum.c \ 70 $(OPIEDIR)/rsync/checksum.c \
71 $(OPIEDIR)/rsync/command.c \ 71 $(OPIEDIR)/rsync/command.c \
72 $(OPIEDIR)/rsync/delta.c \ 72 $(OPIEDIR)/rsync/delta.c \
73 $(OPIEDIR)/rsync/emit.c \ 73 $(OPIEDIR)/rsync/emit.c \
74 $(OPIEDIR)/rsync/hex.c \ 74 $(OPIEDIR)/rsync/hex.c \
75 $(OPIEDIR)/rsync/job.c \ 75 $(OPIEDIR)/rsync/job.c \
76 $(OPIEDIR)/rsync/mdfour.c \ 76 $(OPIEDIR)/rsync/mdfour.c \
77 $(OPIEDIR)/rsync/mksum.c \ 77 $(OPIEDIR)/rsync/mksum.c \
78 $(OPIEDIR)/rsync/msg.c \ 78 $(OPIEDIR)/rsync/msg.c \
79 $(OPIEDIR)/rsync/netint.c \ 79 $(OPIEDIR)/rsync/netint.c \
80 $(OPIEDIR)/rsync/patch.c \ 80 $(OPIEDIR)/rsync/patch.c \
81 $(OPIEDIR)/rsync/prototab.c \ 81 $(OPIEDIR)/rsync/prototab.c \
82 $(OPIEDIR)/rsync/readsums.c \ 82 $(OPIEDIR)/rsync/readsums.c \
83 $(OPIEDIR)/rsync/scoop.c \ 83 $(OPIEDIR)/rsync/scoop.c \
84 $(OPIEDIR)/rsync/search.c \ 84 $(OPIEDIR)/rsync/search.c \
85 $(OPIEDIR)/rsync/stats.c \ 85 $(OPIEDIR)/rsync/stats.c \
86 $(OPIEDIR)/rsync/stream.c \ 86 $(OPIEDIR)/rsync/stream.c \
87 $(OPIEDIR)/rsync/sumset.c \ 87 $(OPIEDIR)/rsync/sumset.c \
88 $(OPIEDIR)/rsync/trace.c \ 88 $(OPIEDIR)/rsync/trace.c \
89 $(OPIEDIR)/rsync/tube.c \ 89 $(OPIEDIR)/rsync/tube.c \
90 $(OPIEDIR)/rsync/util.c \ 90 $(OPIEDIR)/rsync/util.c \
91 $(OPIEDIR)/rsync/version.c \ 91 $(OPIEDIR)/rsync/version.c \
92 $(OPIEDIR)/rsync/whole.c \ 92 $(OPIEDIR)/rsync/whole.c \
93 $(OPIEDIR)/rsync/qrsync.cpp 93 $(OPIEDIR)/rsync/qrsync.cpp
94 INTERFACES= syncdialog.ui 94 INTERFACES= syncdialog.ui
95INCLUDEPATH += $(OPIEDIR)/include 95INCLUDEPATH += $(OPIEDIR)/include
96 DEPENDPATH+= $(OPIEDIR)/include . 96 DEPENDPATH+= $(OPIEDIR)/include .
97INCLUDEPATH += $(OPIEDIR)/core/apps/calibrate 97INCLUDEPATH += $(OPIEDIR)/core/apps/calibrate
98 DEPENDPATH+= $(OPIEDIR)/core/apps/calibrate 98 DEPENDPATH+= $(OPIEDIR)/core/apps/calibrate
99INCLUDEPATH += $(OPIEDIR)/rsync 99INCLUDEPATH += $(OPIEDIR)/rsync
100 DEPENDPATH+= $(OPIEDIR)/rsync 100 DEPENDPATH+= $(OPIEDIR)/rsync
101 TARGET = qpe 101 TARGET = qpe
102 LIBS += -lqpe -lcrypt -lopie 102 LIBS += -lqpe -lcrypt -lopie -luuid
103 103
104TRANSLATIONS = ../../i18n/de/qpe.ts \ 104TRANSLATIONS = ../../i18n/de/qpe.ts \
105 ../../i18n/en/qpe.ts \ 105 ../../i18n/en/qpe.ts \
106 ../../i18n/es/qpe.ts \ 106 ../../i18n/es/qpe.ts \
107 ../../i18n/fr/qpe.ts \ 107 ../../i18n/fr/qpe.ts \
108 ../../i18n/hu/qpe.ts \ 108 ../../i18n/hu/qpe.ts \
109 ../../i18n/ja/qpe.ts \ 109 ../../i18n/ja/qpe.ts \
110 ../../i18n/ko/qpe.ts \ 110 ../../i18n/ko/qpe.ts \
111 ../../i18n/no/qpe.ts \ 111 ../../i18n/no/qpe.ts \
112 ../../i18n/pl/qpe.ts \ 112 ../../i18n/pl/qpe.ts \
113 ../../i18n/pt/qpe.ts \ 113 ../../i18n/pt/qpe.ts \
114 ../../i18n/pt_BR/qpe.ts \ 114 ../../i18n/pt_BR/qpe.ts \
115 ../../i18n/sl/qpe.ts \ 115 ../../i18n/sl/qpe.ts \
116 ../../i18n/zh_CN/qpe.ts \ 116 ../../i18n/zh_CN/qpe.ts \
117 ../../i18n/zh_TW/qpe.ts 117 ../../i18n/zh_TW/qpe.ts
diff --git a/core/launcher/qcopbridge.cpp b/core/launcher/qcopbridge.cpp
index 2d084fc..85993ee 100644
--- a/core/launcher/qcopbridge.cpp
+++ b/core/launcher/qcopbridge.cpp
@@ -1,420 +1,424 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of 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#ifdef QWS
24#include <qpe/qcopenvelope_qws.h> 25#include <qpe/qcopenvelope_qws.h>
26#endif
25#include <qpe/qpeapplication.h> 27#include <qpe/qpeapplication.h>
28#include <qpe/version.h>
26 29
27#include <qdir.h> 30#include <qdir.h>
28#include <qfile.h> 31#include <qfile.h>
29#include <qtextstream.h> 32#include <qtextstream.h>
30#include <qdatastream.h> 33#include <qdatastream.h>
31#include <qstringlist.h> 34#include <qstringlist.h>
32#include <qfileinfo.h> 35#include <qfileinfo.h>
33#include <qregexp.h> 36#include <qregexp.h>
37#ifdef QWS
34#include <qcopchannel_qws.h> 38#include <qcopchannel_qws.h>
39#endif
35 40
36// actually this is wrong, _XOPEN_SOURCE should get defined on the commandline
37// and it should have a proper value assigned. (Simon)
38#if !defined(_XOPEN_SOURCE)
39#define _XOPEN_SOURCE 41#define _XOPEN_SOURCE
40#endif
41#include <pwd.h> 42#include <pwd.h>
42#include <sys/types.h> 43#include <sys/types.h>
43#include <unistd.h> 44#include <unistd.h>
44 45
45#if defined(_OS_LINUX_) 46#if defined(_OS_LINUX_)
46#include <shadow.h> 47#include <shadow.h>
47#endif 48#endif
48 49
49//#define INSECURE 50//#define INSECURE
50 51
51const int block_size = 51200; 52const int block_size = 51200;
52 53
53QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent, 54QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent ,
54 const char* name ) 55 const char* name )
55 : QServerSocket( port, 1, parent, name ), 56 : QServerSocket( port, 1, parent, name ),
56 desktopChannel( 0 ), 57 desktopChannel( 0 ),
57 cardChannel( 0 ) 58 cardChannel( 0 )
58{ 59{
59 if ( !ok() ) 60 if ( !ok() )
60 qWarning( "Failed to bind to port %d", port ); 61 qWarning( "Failed to bind to port %d", port );
61 else { 62 else {
62 desktopChannel = new QCopChannel( "QPE/Desktop", this ); 63#ifndef QT_NO_COP
63 connect( desktopChannel, SIGNAL(received(const QCString &, const QByteArray &)), 64 desktopChannel = new QCopChannel( "QPE/Desktop", this );
64 this, SLOT(desktopMessage( const QCString &, const QByteArray &)) ); 65 connect( desktopChannel, SIGNAL(received(const QCString &, const QByteArray &)),
65 cardChannel = new QCopChannel( "QPE/Card", this ); 66 this, SLOT(desktopMessage( const QCString &, const QByteArray &)) );
66 connect( cardChannel, SIGNAL(received(const QCString &, const QByteArray &)), 67 cardChannel = new QCopChannel( "QPE/Card", this );
67 this, SLOT(desktopMessage( const QCString &, const QByteArray &)) ); 68 connect( cardChannel, SIGNAL(received(const QCString &, const QByteArray &)),
69 this, SLOT(desktopMessage( const QCString &, const QByteArray &)) );
70#endif
68 } 71 }
69 sendSync = FALSE; 72 sendSync = FALSE;
70} 73}
71 74
72QCopBridge::~QCopBridge() 75QCopBridge::~QCopBridge()
73{ 76{
77#ifndef QT_NO_COP
74 delete desktopChannel; 78 delete desktopChannel;
79#endif
75} 80}
76 81
77void QCopBridge::newConnection( int socket ) 82void QCopBridge::newConnection( int socket )
78{ 83{
79 QCopBridgePI *pi = new QCopBridgePI( socket, this ); 84 QCopBridgePI *pi = new QCopBridgePI( socket, this );
80 openConnections.append( pi ); 85 openConnections.append( pi );
81 connect ( pi, SIGNAL( connectionClosed( QCopBridgePI *) ), this, SLOT( connectionClosed( QCopBridgePI *) ) ); 86 connect ( pi, SIGNAL( connectionClosed( QCopBridgePI *) ), this, SLOT( connectionClosed( QCopBridgePI *) ) );
87#ifndef QT_NO_COP
82 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::DisableSuspend; 88 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::DisableSuspend;
83 89#endif
90
84 if ( sendSync ) { 91 if ( sendSync ) {
85 pi ->startSync(); 92 pi ->startSync();
86 sendSync = FALSE; 93 sendSync = FALSE;
87 } 94 }
88} 95}
89 96
90void QCopBridge::connectionClosed( QCopBridgePI *pi ) 97void QCopBridge::connectionClosed( QCopBridgePI *pi )
91{ 98{
92 openConnections.remove( pi ); 99 openConnections.remove( pi );
93 if ( openConnections.count() == 0 ) { 100 if ( openConnections.count() == 0 ) {
94 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable; 101#ifndef QT_NO_COP
102 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
103#endif
95 } 104 }
96} 105}
97 106
98void QCopBridge::closeOpenConnections() 107void QCopBridge::closeOpenConnections()
99{ 108{
100 QCopBridgePI *pi; 109 QCopBridgePI *pi;
101 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) 110 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() )
102 pi->close(); 111 pi->close();
103} 112}
104 113
105 114
106void QCopBridge::desktopMessage( const QCString &command, const QByteArray &args ) 115void QCopBridge::desktopMessage( const QCString &command, const QByteArray &args )
107{ 116{
108 command.stripWhiteSpace(); 117 command.stripWhiteSpace();
109 118
110 int paren = command.find( "(" ); 119 int paren = command.find( "(" );
111 if ( paren <= 0 ) { 120 if ( paren <= 0 ) {
112 qDebug("DesktopMessage: bad qcop syntax"); 121 qDebug("DesktopMessage: bad qcop syntax");
113 return; 122 return;
114 } 123 }
115 124
116 QString params = command.mid( paren + 1 ); 125 QString params = command.mid( paren + 1 );
117 if ( params[params.length()-1] != ')' ) { 126 if ( params[params.length()-1] != ')' ) {
118 qDebug("DesktopMessage: bad qcop syntax"); 127 qDebug("DesktopMessage: bad qcop syntax");
119 return; 128 return;
120 } 129 }
121 130
122 params.truncate( params.length()-1 ); 131 params.truncate( params.length()-1 );
123 132
124 QStringList paramList = QStringList::split( ",", params ); 133 QStringList paramList = QStringList::split( ",", params );
125 QString data; 134 QString data;
126 if ( paramList.count() ) { 135 if ( paramList.count() ) {
127 QDataStream stream( args, IO_ReadOnly ); 136 QDataStream stream( args, IO_ReadOnly );
128 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) { 137 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) {
129 QString str; 138 QString str;
130 if ( *it == "QString" ) { 139 if ( *it == "QString" ) {
131 stream >> str; 140 stream >> str;
132 } else if ( *it == "QCString" ) { 141 } else if ( *it == "QCString" ) {
133 QCString cstr; 142 QCString cstr;
134 stream >> cstr; 143 stream >> cstr;
135 str = QString::fromLocal8Bit( cstr ); 144 str = QString::fromLocal8Bit( cstr );
136 } else if ( *it == "int" ) { 145 } else if ( *it == "int" ) {
137 int i; 146 int i;
138 stream >> i; 147 stream >> i;
139 str = QString::number( i ); 148 str = QString::number( i );
140 } else if ( *it == "bool" ) { 149 } else if ( *it == "bool" ) {
141 int i; 150 int i;
142 stream >> i; 151 stream >> i;
143 str = QString::number( i ); 152 str = QString::number( i );
144 } else { 153 } else {
145 qDebug(" cannot route the argument type %s through the qcop bridge", (*it).latin1() ); 154 qDebug(" cannot route the argument type %s throught the qcop bridge", (*it).latin1() );
146 return; 155 return;
147 } 156 }
148 str.replace( QRegExp("&"), "&amp;" ); 157 QString estr;
149 str.replace( QRegExp(" "), "&0x20;" ); 158 for (int i=0; i<(int)str.length(); i++) {
150 str.replace( QRegExp("\n"), "&0x0d;" ); 159 QChar ch = str[i];
151 str.replace( QRegExp("\r"), "&0x0a;" ); 160 if ( ch.row() )
152 data += " " + str; 161 goto quick;
153 } 162 switch (ch.cell()) {
163 case '&':
164 estr.append( "&amp;" );
165 break;
166 case ' ':
167 estr.append( "&0x20;" );
168 break;
169 case '\n':
170 estr.append( "&0x0d;" );
171 break;
172 case '\r':
173 estr.append( "&0x0a;" );
174 break;
175 default: quick:
176 estr.append(ch);
177 }
178 }
179 data += " " + estr;
180 }
154 } 181 }
155 QString sendCommand = QString(command.data()) + data; 182 QString sendCommand = QString(command.data()) + data;
156 // send the command to all open connections 183 // send the command to all open connections
157 if ( command == "startSync()" ) { 184 if ( command == "startSync()" ) {
158 // we need to buffer it a bit 185 // we need to buffer it a bit
159 sendSync = TRUE; 186 sendSync = TRUE;
160 startTimer( 20000 ); 187 startTimer( 20000 );
161 } 188 }
162 189
163 QCopBridgePI *pi; 190 QCopBridgePI *pi;
164 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) { 191 for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) {
165 pi->sendDesktopMessage( sendCommand ); 192 pi->sendDesktopMessage( sendCommand );
166 } 193 }
167} 194}
168 195
169void QCopBridge::timerEvent( QTimerEvent * ) 196void QCopBridge::timerEvent( QTimerEvent * )
170{ 197{
171 sendSync = FALSE; 198 sendSync = FALSE;
172 killTimers(); 199 killTimers();
173} 200}
174 201
175 202
176QCopBridgePI::QCopBridgePI( int socket, QObject *parent, const char* name ) 203QCopBridgePI::QCopBridgePI( int socket, QObject *parent , const char* name )
177 : QSocket( parent, name ) 204 : QSocket( parent, name )
178{ 205{
179 setSocket( socket ); 206 setSocket( socket );
180 207
181 peerport = peerPort(); 208 peerport = peerPort();
182 peeraddress = peerAddress(); 209 peeraddress = peerAddress();
183 210
184#ifndef INSECURE 211#ifndef INSECURE
185 if ( !accessAuthorized(peeraddress) ) { 212 if ( !SyncAuthentication::isAuthorized(peeraddress) ) {
186 state = Forbidden; 213 state = Forbidden;
187 startTimer( 0 ); 214 startTimer( 0 );
188 } else 215 } else
189#endif 216 #endif
190 { 217 {
191 state = Connected; 218 state = Connected;
192 sendSync = FALSE; 219 sendSync = FALSE;
193 connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); 220 connect( this, SIGNAL( readyRead() ), SLOT( read() ) );
194 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); 221 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
195 222
196 send( "220 Qtopia QCop bridge ready!" ); 223 QString intro="220 Qtopia ";
197 state = Wait_USER; 224 intro += QPE_VERSION; intro += ";";
198 225 intro += "challenge="; intro += SyncAuthentication::serverId(); intro += ";";
199 // idle timer to close connections when not used anymore 226 intro += "loginname="; intro += SyncAuthentication::loginName(); intro += ";";
200 startTimer( 60000 ); 227 intro += "displayname="; intro += SyncAuthentication::ownerName(); intro += ";";
201 connected = TRUE; 228 send( intro );
229 state = Wait_USER;
230
231 // idle timer to close connections when not used anymore
232 startTimer( 60000 );
233 connected = TRUE;
202 } 234 }
203} 235}
204 236
205 237
206QCopBridgePI::~QCopBridgePI() 238QCopBridgePI::~QCopBridgePI()
207{ 239{
208 240
209} 241}
210 242
211void QCopBridgePI::connectionClosed() 243void QCopBridgePI::connectionClosed()
212{ 244{
213 emit connectionClosed( this ); 245 emit connectionClosed( this );
214 // qDebug( "Debug: Connection closed" ); 246 // qDebug( "Debug: Connection closed" );
215 delete this; 247 delete this;
216} 248}
217 249
218void QCopBridgePI::sendDesktopMessage( const QString &msg ) 250void QCopBridgePI::sendDesktopMessage( const QString &msg )
219{ 251{
220 QString str = "CALL QPE/Desktop " + msg; 252 QString str = "CALL QPE/Desktop " + msg;
221 send ( str ); 253 send ( str );
222} 254}
223 255
224 256
225void QCopBridgePI::send( const QString& msg ) 257void QCopBridgePI::send( const QString& msg )
226{ 258{
227 QTextStream os( this ); 259 QTextStream os( this );
228 os << msg << endl; 260 os << msg << endl;
229 //qDebug( "sending qcop message: %s", msg.latin1() ); 261 //qDebug( "sending qcop message: %s", msg.latin1() );
230} 262}
231 263
232void QCopBridgePI::read() 264void QCopBridgePI::read()
233{ 265{
234 while ( canReadLine() ) 266 while ( canReadLine() )
235 process( readLine().stripWhiteSpace() ); 267 process( readLine().stripWhiteSpace() );
236}
237
238bool QCopBridgePI::checkUser( const QString& user )
239{
240 if ( user.isEmpty() ) return FALSE;
241
242 struct passwd *pw;
243 pw = getpwuid( geteuid() );
244 QString euser = QString::fromLocal8Bit( pw->pw_name );
245 return user == euser;
246}
247
248bool QCopBridgePI::checkPassword( const QString& password )
249{
250 // ### HACK for testing on local host
251 return true;
252
253 /*
254 struct passwd *pw = 0;
255 struct spwd *spw = 0;
256
257 pw = getpwuid( geteuid() );
258 spw = getspnam( pw->pw_name );
259
260 QString cpwd = QString::fromLocal8Bit( pw->pw_passwd );
261 if ( cpwd == "x" && spw )
262 cpwd = QString::fromLocal8Bit( spw->sp_pwdp );
263
264 QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) );
265 return cpwd == cpassword;
266*/
267} 268}
268 269
269void QCopBridgePI::process( const QString& message ) 270void QCopBridgePI::process( const QString& message )
270{ 271{
271 //qDebug( "Command: %s", message.latin1() ); 272 //qDebug( "Command: %s", message.latin1() );
272 273
273 // split message using "," as separator 274 // split message using "," as separator
274 QStringList msg = QStringList::split( " ", message ); 275 QStringList msg = QStringList::split( " ", message );
275 if ( msg.isEmpty() ) return; 276 if ( msg.isEmpty() ) return;
276 277
277 // command token 278 // command token
278 QString cmd = msg[0].upper(); 279 QString cmd = msg[0].upper();
279 280
280 // argument token 281 // argument token
281 QString arg; 282 QString arg;
282 if ( msg.count() >= 2 ) 283 if ( msg.count() >= 2 )
283 arg = msg[1]; 284 arg = msg[1];
284 285
285 // we always respond to QUIT, regardless of state 286 // we always respond to QUIT, regardless of state
286 if ( cmd == "QUIT" ) { 287 if ( cmd == "QUIT" ) {
287 send( "211 Have a nice day!" ); 288 send( "211 Have a nice day!" );
288 delete this; 289 delete this;
289 return; 290 return;
290 } 291 }
291 292
292 // connected to client 293 // connected to client
293 if ( Connected == state ) 294 if ( Connected == state )
294 return; 295 return;
295 296
296 // waiting for user name 297 // waiting for user name
297 if ( Wait_USER == state ) { 298 if ( Wait_USER == state ) {
298 299
299 if ( cmd != "USER" || msg.count() < 2 || !checkUser( arg ) ) { 300 if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) {
300 send( "530 Please login with USER and PASS" ); 301 send( "530 Please login with USER and PASS" );
301 return; 302 return;
302 } 303 }
303 send( "331 User name ok, need password" ); 304 send( "331 User name ok, need password" );
304 state = Wait_PASS; 305 state = Wait_PASS;
305 return; 306 return;
306 } 307 }
307 308
308 // waiting for password 309 // waiting for password
309 if ( Wait_PASS == state ) { 310 if ( Wait_PASS == state ) {
310 311
311 if ( cmd != "PASS" || !checkPassword( arg ) ) { 312 if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) {
312 //if ( cmd != "PASS" || msg.count() < 2 || !checkPassword( arg ) ) { 313 send( "530 Please login with USER and PASS" );
313 send( "530 Please login with USER and PASS" ); 314 return;
314 return; 315 }
315 } 316 send( "230 User logged in, proceed" );
316 send( "230 User logged in, proceed" ); 317 state = Ready;
317 state = Ready; 318 if ( sendSync ) {
318 if ( sendSync ) { 319 sendDesktopMessage( "startSync()" );
319 sendDesktopMessage( "startSync()" ); 320 sendSync = FALSE;
320 sendSync = FALSE; 321 }
321 } 322 return;
322 return;
323 } 323 }
324 324
325 // noop (NOOP) 325 // noop (NOOP)
326 else if ( cmd == "NOOP" ) { 326 else if ( cmd == "NOOP" ) {
327 connected = TRUE; 327 connected = TRUE;
328 send( "200 Command okay" ); 328 send( "200 Command okay" );
329 } 329 }
330 330
331 // call (CALL) 331 // call (CALL)
332 else if ( cmd == "CALL" ) { 332 else if ( cmd == "CALL" ) {
333 333
334 // example: call QPE/System execute(QString) addressbook 334 // example: call QPE/System execute(QString) addressbook
335 335
336 if ( msg.count() < 3 ) { 336 if ( msg.count() < 3 ) {
337 send( "500 Syntax error, command unrecognized" ); 337 send( "500 Syntax error, command unrecognized" );
338 } 338 }
339 else { 339 else {
340 340
341 QString channel = msg[1]; 341 QString channel = msg[1];
342 QString command = msg[2]; 342 QString command = msg[2];
343 343
344 command.stripWhiteSpace(); 344 command.stripWhiteSpace();
345 345
346 int paren = command.find( "(" ); 346 int paren = command.find( "(" );
347 if ( paren <= 0 ) { 347 if ( paren <= 0 ) {
348 send( "500 Syntax error, command unrecognized" ); 348 send( "500 Syntax error, command unrecognized" );
349 return; 349 return;
350 } 350 }
351 351
352 QString params = command.mid( paren + 1 ); 352 QString params = command.mid( paren + 1 );
353 if ( params[params.length()-1] != ')' ) { 353 if ( params[params.length()-1] != ')' ) {
354 send( "500 Syntax error, command unrecognized" ); 354 send( "500 Syntax error, command unrecognized" );
355 return; 355 return;
356 } 356 }
357 357
358 params.truncate( params.length()-1 ); 358 params.truncate( params.length()-1 );
359 QByteArray buffer; 359 QByteArray buffer;
360 QDataStream ds( buffer, IO_WriteOnly ); 360 QDataStream ds( buffer, IO_WriteOnly );
361 361
362 int msgId = 3; 362 int msgId = 3;
363 363
364 QStringList paramList = QStringList::split( ",", params ); 364 QStringList paramList = QStringList::split( ",", params );
365 if ( paramList.count() > msg.count() - 3 ) { 365 if ( paramList.count() > msg.count() - 3 ) {
366 send( "500 Syntax error, command unrecognized" ); 366 send( "500 Syntax error, command unrecognized" );
367 return; 367 return;
368 } 368 }
369 369
370 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) { 370 for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) {
371 371
372 QString arg = msg[msgId]; 372 QString arg = msg[msgId];
373 arg.replace( QRegExp("&0x20;"), " " ); 373 arg.replace( QRegExp("&0x20;"), " " );
374 arg.replace( QRegExp("&amp;"), "&" ); 374 arg.replace( QRegExp("&amp;"), "&" );
375 arg.replace( QRegExp("&0x0d;"), "\n" ); 375 arg.replace( QRegExp("&0x0d;"), "\n" );
376 arg.replace( QRegExp("&0x0a;"), "\r" ); 376 arg.replace( QRegExp("&0x0a;"), "\r" );
377 if ( *it == "QString" ) 377 if ( *it == "QString" )
378 ds << arg; 378 ds << arg;
379 else if ( *it == "QCString" ) 379 else if ( *it == "QCString" )
380 ds << arg.local8Bit(); 380 ds << arg.local8Bit();
381 else if ( *it == "int" ) 381 else if ( *it == "int" )
382 ds << arg.toInt(); 382 ds << arg.toInt();
383 else if ( *it == "bool" ) 383 else if ( *it == "bool" )
384 ds << arg.toInt(); 384 ds << arg.toInt();
385 else { 385 else {
386 send( "500 Syntax error, command unrecognized" ); 386 send( "500 Syntax error, command unrecognized" );
387 return; 387 return;
388 } 388 }
389 msgId++; 389 msgId++;
390 } 390 }
391 391
392 if ( !QCopChannel::isRegistered( channel.latin1() ) ) { 392#ifndef QT_NO_COP
393 // send message back about it 393 if ( !QCopChannel::isRegistered( channel.latin1() ) ) {
394 QString answer = "599 ChannelNotRegistered " + channel; 394 // send message back about it
395 send( answer ); 395 QString answer = "599 ChannelNotRegistered " + channel;
396 return; 396 send( answer );
397 } 397 return;
398 398 }
399 if ( paramList.count() ) 399#endif
400 QCopChannel::send( channel.latin1(), command.latin1(), buffer ); 400
401 else 401#ifndef QT_NO_COP
402 QCopChannel::send( channel.latin1(), command.latin1() ); 402 if ( paramList.count() )
403 403 QCopChannel::send( channel.latin1(), command.latin1(), buffer );
404 send( "200 Command okay" ); 404 else
405 } 405 QCopChannel::send( channel.latin1(), command.latin1() );
406
407 send( "200 Command okay" );
408#endif
409 }
406 } 410 }
407 // not implemented 411 // not implemented
408 else 412 else
409 send( "502 Command not implemented" ); 413 send( "502 Command not implemented" );
410} 414}
411 415
412 416
413 417
414void QCopBridgePI::timerEvent( QTimerEvent * ) 418void QCopBridgePI::timerEvent( QTimerEvent * )
415{ 419{
416 if ( connected ) 420 if ( connected )
417 connected = FALSE; 421 connected = FALSE;
418 else 422 else
419 connectionClosed(); 423 connectionClosed();
420} 424}
diff --git a/core/launcher/qcopbridge.h b/core/launcher/qcopbridge.h
index 114b3ee..408d10d 100644
--- a/core/launcher/qcopbridge.h
+++ b/core/launcher/qcopbridge.h
@@ -1,36 +1,36 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of 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#ifndef __qcopbridge_h__ 20#ifndef __qcopbridge_h__
21#define __qcopbridge_h__ 21#define __qcopbridge_h__
22 22
23#include <qserversocket.h> 23#include <qserversocket.h>
24#include <qsocket.h> 24#include <qsocket.h>
25#include <qdir.h> 25#include <qdir.h>
26#include <qfile.h> 26#include <qfile.h>
27#include <qbuffer.h> 27#include <qbuffer.h>
28 28
29class QFileInfo; 29class QFileInfo;
30class QCopBridgePI; 30class QCopBridgePI;
31class QCopChannel; 31class QCopChannel;
32 32
33class QCopBridge : public QServerSocket 33class QCopBridge : public QServerSocket
34{ 34{
35 Q_OBJECT 35 Q_OBJECT
36 36
@@ -50,46 +50,43 @@ protected:
50 50
51private: 51private:
52 QCopChannel *desktopChannel; 52 QCopChannel *desktopChannel;
53 QCopChannel *cardChannel; 53 QCopChannel *cardChannel;
54 QList<QCopBridgePI> openConnections; 54 QList<QCopBridgePI> openConnections;
55 bool sendSync; 55 bool sendSync;
56}; 56};
57 57
58 58
59class QCopBridgePI : public QSocket 59class QCopBridgePI : public QSocket
60{ 60{
61 Q_OBJECT 61 Q_OBJECT
62 62
63 enum State { Connected, Wait_USER, Wait_PASS, Ready, Forbidden }; 63 enum State { Connected, Wait_USER, Wait_PASS, Ready, Forbidden };
64 64
65public: 65public:
66 QCopBridgePI( int socket, QObject *parent = 0, const char* name = 0 ); 66 QCopBridgePI( int socket, QObject *parent = 0, const char* name = 0 );
67 virtual ~QCopBridgePI(); 67 virtual ~QCopBridgePI();
68 68
69 void sendDesktopMessage( const QString &msg ); 69 void sendDesktopMessage( const QString &msg );
70 void startSync() { sendSync = TRUE; } 70 void startSync() { sendSync = TRUE; }
71 71
72signals: 72signals:
73 void connectionClosed( QCopBridgePI *); 73 void connectionClosed( QCopBridgePI *);
74 74
75protected slots: 75protected slots:
76 void read(); 76 void read();
77 void send( const QString& msg ); 77 void send( const QString& msg );
78 void process( const QString& command ); 78 void process( const QString& command );
79 void connectionClosed(); 79 void connectionClosed();
80 80
81protected: 81protected:
82 bool checkUser( const QString& user );
83 bool checkPassword( const QString& pw );
84
85 void timerEvent( QTimerEvent *e ); 82 void timerEvent( QTimerEvent *e );
86 83
87private: 84private:
88 State state; 85 State state;
89 Q_UINT16 peerport; 86 Q_UINT16 peerport;
90 QHostAddress peeraddress; 87 QHostAddress peeraddress;
91 bool connected; 88 bool connected;
92 bool sendSync; 89 bool sendSync;
93}; 90};
94 91
95#endif 92#endif
diff --git a/core/launcher/transferserver.cpp b/core/launcher/transferserver.cpp
index 7294f9c..a6dab07 100644
--- a/core/launcher/transferserver.cpp
+++ b/core/launcher/transferserver.cpp
@@ -1,216 +1,304 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of 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#define _XOPEN_SOURCE 20#define _XOPEN_SOURCE
21#include <pwd.h> 21#include <pwd.h>
22#include <sys/types.h> 22#include <sys/types.h>
23#include <unistd.h> 23#include <unistd.h>
24#include <stdlib.h> 24#include <stdlib.h>
25#include <time.h>
26#include <shadow.h>
27
28extern "C" {
29#include <uuid/uuid.h>
30#define UUID_H_INCLUDED
31}
25 32
26#if defined(_OS_LINUX_) 33#if defined(_OS_LINUX_)
27#include <shadow.h> 34#include <shadow.h>
28#endif 35#endif
29 36
30#include <qdir.h> 37#include <qdir.h>
31#include <qfile.h> 38#include <qfile.h>
32#include <qtextstream.h> 39#include <qtextstream.h>
33#include <qdatastream.h> 40#include <qdatastream.h>
34#include <qmessagebox.h> 41#include <qmessagebox.h>
35#include <qstringlist.h> 42#include <qstringlist.h>
36#include <qfileinfo.h> 43#include <qfileinfo.h>
37#include <qregexp.h> 44#include <qregexp.h>
38//#include <qpe/qcopchannel_qws.h> 45//#include <qpe/qcopchannel_qws.h>
39#include <qpe/process.h> 46#include <qpe/process.h>
47#include <qpe/global.h>
40#include <qpe/config.h> 48#include <qpe/config.h>
49#include <qpe/contact.h>
50#include <qpe/quuid.h>
51#include <qpe/version.h>
52#ifdef QWS
41#include <qpe/qcopenvelope_qws.h> 53#include <qpe/qcopenvelope_qws.h>
54#endif
42 55
43#include "transferserver.h" 56#include "transferserver.h"
44#include "qprocess.h" 57#include "qprocess.h"
45 58
46const int block_size = 51200; 59const int block_size = 51200;
47 60
48TransferServer::TransferServer( Q_UINT16 port, QObject *parent, 61TransferServer::TransferServer( Q_UINT16 port, QObject *parent ,
49 const char* name ) 62 const char* name )
50 : QServerSocket( port, 1, parent, name ) 63 : QServerSocket( port, 1, parent, name )
51{ 64{
52 if ( !ok() ) 65 if ( !ok() )
53 qWarning( "Failed to bind to port %d", port ); 66 qWarning( "Failed to bind to port %d", port );
54} 67}
55 68
56TransferServer::~TransferServer() 69TransferServer::~TransferServer()
57{ 70{
58 71
59} 72}
60 73
61void TransferServer::newConnection( int socket ) 74void TransferServer::newConnection( int socket )
62{ 75{
63 (void) new ServerPI( socket, this ); 76 (void) new ServerPI( socket, this );
64} 77}
65 78
66bool accessAuthorized(QHostAddress peeraddress) 79QString SyncAuthentication::serverId()
67{ 80{
68 Config cfg("Security"); 81 Config cfg("Security");
69 cfg.setGroup("Sync"); 82 cfg.setGroup("Sync");
70 uint auth_peer = cfg.readNumEntry("auth_peer",0xc0a80100); 83 QString r=cfg.readEntry("serverid");
84 if ( r.isEmpty() ) {
85 uuid_t uuid;
86 uuid_generate( uuid );
87 cfg.writeEntry("serverid",(r = QUuid( uuid ).toString()));
88 }
89 return r;
90}
91
92QString SyncAuthentication::ownerName()
93{
94 QString vfilename = Global::applicationFileName("addressbook",
95 "businesscard.vcf");
96 if (QFile::exists(vfilename)) {
97 Contact c;
98 c = Contact::readVCard( vfilename )[0];
99 return c.fullName();
100 }
101
102 return "";
103}
104
105QString SyncAuthentication::loginName()
106{
107 struct passwd *pw;
108 pw = getpwuid( geteuid() );
109 return QString::fromLocal8Bit( pw->pw_name );
110}
111
112int SyncAuthentication::isAuthorized(QHostAddress peeraddress)
113{
114 Config cfg("Security");
115 cfg.setGroup("Sync");
116 QString allowedstr = cfg.readEntry("auth_peer","192.168.1.0");
117 QHostAddress allowed;
118 allowed.setAddress(allowedstr);
119 uint auth_peer = allowed.ip4Addr();
71 uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits",24); 120 uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits",24);
72 bool ok = (peeraddress.ip4Addr() & (((1<<auth_peer_bits)-1)<<(32-auth_peer_bits))) 121 uint mask = auth_peer_bits >= 32 // shifting by 32 is not defined
73 == auth_peer; 122 ? 0xffffffff : (((1<<auth_peer_bits)-1)<<(32-auth_peer_bits));
74 /* Allows denial-of-service attack. 123 return (peeraddress.ip4Addr() & mask) == auth_peer;
75 if ( !ok ) { 124}
76 QMessageBox::warning(0,tr("Security"), 125
77 tr("<p>An attempt to access this device from %1 has been denied.") 126bool SyncAuthentication::checkUser( const QString& user )
78 .arg(peeraddress.toString())); 127{
79 } 128 if ( user.isEmpty() ) return FALSE;
80 */ 129 QString euser = loginName();
81 return ok; 130 return user == euser;
82} 131}
83 132
84ServerPI::ServerPI( int socket, QObject *parent, const char* name ) 133bool SyncAuthentication::checkPassword( const QString& password )
134{
135#ifdef ALLOW_UNIX_USER_FTP
136 // First, check system password...
137
138 struct passwd *pw = 0;
139 struct spwd *spw = 0;
140
141 pw = getpwuid( geteuid() );
142 spw = getspnam( pw->pw_name );
143
144 QString cpwd = QString::fromLocal8Bit( pw->pw_passwd );
145 if ( cpwd == "x" && spw )
146 cpwd = QString::fromLocal8Bit( spw->sp_pwdp );
147
148 // Note: some systems use more than crypt for passwords.
149 QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) );
150 if ( cpwd == cpassword )
151 return TRUE;
152#endif
153
154 static int lastdenial=0;
155 static int denials=0;
156 int now = time(0);
157
158 // Detect old Qtopia Desktop (no password)
159 if ( password.isEmpty() ) {
160 if ( denials < 1 || now > lastdenial+600 ) {
161 QMessageBox::warning( 0,tr("Sync Connection"),
162 tr("<p>An unauthorized system is requesting access to this device."
163 "<p>If you are using a version of Qtopia Desktop older than 1.5.1, "
164 "please upgrade."),
165 tr("Deny") );
166 denials++;
167 lastdenial=now;
168 }
169 return FALSE;
170 }
171
172 // Second, check sync password...
173 if ( password.left(6) == "Qtopia" ) {
174 QString cpassword = QString::fromLocal8Bit( crypt( password.mid(8).local8Bit(), "qp" ) );
175 Config cfg("Security");
176 cfg.setGroup("Sync");
177 QString pwds = cfg.readEntry("Passwords");
178 if ( QStringList::split(QChar(' '),pwds).contains(cpassword) )
179 return TRUE;
180
181 // Unrecognized system. Be careful...
182
183 if ( (denials > 2 && now < lastdenial+600)
184 || QMessageBox::warning(0,tr("Sync Connection"),
185 tr("<p>An unrecognized system is requesting access to this device."
186 "<p>If you have just initiated a Sync for the first time, this is normal."),
187 tr("Allow"),tr("Deny"))==1 )
188 {
189 denials++;
190 lastdenial=now;
191 return FALSE;
192 } else {
193 denials=0;
194 cfg.writeEntry("Passwords",pwds+" "+cpassword);
195 return TRUE;
196 }
197 }
198
199 return FALSE;
200}
201
202
203ServerPI::ServerPI( int socket, QObject *parent , const char* name )
85 : QSocket( parent, name ) , dtp( 0 ), serversocket( 0 ), waitsocket( 0 ) 204 : QSocket( parent, name ) , dtp( 0 ), serversocket( 0 ), waitsocket( 0 )
86{ 205{
87 state = Connected; 206 state = Connected;
88 207
89 setSocket( socket ); 208 setSocket( socket );
90 209
91 peerport = peerPort(); 210 peerport = peerPort();
92 peeraddress = peerAddress(); 211 peeraddress = peerAddress();
93 212
94#ifndef INSECURE 213#ifndef INSECURE
95 if ( !accessAuthorized(peeraddress) ) { 214 if ( !SyncAuthentication::isAuthorized(peeraddress) ) {
96 state = Forbidden; 215 state = Forbidden;
97 startTimer( 0 ); 216 startTimer( 0 );
98 } else 217 } else
99 #endif 218 #endif
100 { 219 {
101 connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); 220 connect( this, SIGNAL( readyRead() ), SLOT( read() ) );
102 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); 221 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
103 222
104 passiv = FALSE; 223 passiv = FALSE;
105 for( int i = 0; i < 4; i++ ) 224 for( int i = 0; i < 4; i++ )
106 wait[i] = FALSE; 225 wait[i] = FALSE;
107 226
108 send( "220 Qtopia transfer service ready!" ); 227 send( "220 Qtopia " QPE_VERSION " FTP Server" );
109 state = Wait_USER; 228 state = Wait_USER;
110 229
111 dtp = new ServerDTP( this ); 230 dtp = new ServerDTP( this );
112 connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) ); 231 connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) );
113 connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) ); 232 connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) );
114 connect( dtp, SIGNAL( error( int ) ), SLOT( dtpError( int ) ) ); 233 connect( dtp, SIGNAL( error( int ) ), SLOT( dtpError( int ) ) );
115 234
116 235
117 directory = QDir::currentDirPath(); 236 directory = QDir::currentDirPath();
118 237
119 static int p = 1024; 238 static int p = 1024;
120 239
121 while ( !serversocket || !serversocket->ok() ) { 240 while ( !serversocket || !serversocket->ok() ) {
122 delete serversocket; 241 delete serversocket;
123 serversocket = new ServerSocket( ++p, this ); 242 serversocket = new ServerSocket( ++p, this );
124 } 243 }
125 connect( serversocket, SIGNAL( newIncomming( int ) ), 244 connect( serversocket, SIGNAL( newIncomming( int ) ),
126 SLOT( newConnection( int ) ) ); 245 SLOT( newConnection( int ) ) );
127 } 246 }
128} 247}
129 248
130ServerPI::~ServerPI() 249ServerPI::~ServerPI()
131{ 250{
132 251
133} 252}
134 253
135void ServerPI::connectionClosed() 254void ServerPI::connectionClosed()
136{ 255{
137 // qDebug( "Debug: Connection closed" ); 256 // qDebug( "Debug: Connection closed" );
138 delete this; 257 delete this;
139} 258}
140 259
141void ServerPI::send( const QString& msg ) 260void ServerPI::send( const QString& msg )
142{ 261{
143 QTextStream os( this ); 262 QTextStream os( this );
144 os << msg << endl; 263 os << msg << endl;
145 //qDebug( "Reply: %s", msg.latin1() ); 264 //qDebug( "Reply: %s", msg.latin1() );
146} 265}
147 266
148void ServerPI::read() 267void ServerPI::read()
149{ 268{
150 while ( canReadLine() ) 269 while ( canReadLine() )
151 process( readLine().stripWhiteSpace() ); 270 process( readLine().stripWhiteSpace() );
152} 271}
153 272
154bool ServerPI::checkUser( const QString& user )
155{
156 if ( user.isEmpty() ) return FALSE;
157
158 struct passwd *pw;
159 pw = getpwuid( geteuid() );
160 QString euser = QString::fromLocal8Bit( pw->pw_name );
161 return user == euser;
162}
163
164bool ServerPI::checkPassword( const QString& /* password */ )
165{
166 // ### HACK for testing on local host
167 return true;
168
169 /*
170 struct passwd *pw = 0;
171 struct spwd *spw = 0;
172
173 pw = getpwuid( geteuid() );
174 spw = getspnam( pw->pw_name );
175
176 QString cpwd = QString::fromLocal8Bit( pw->pw_passwd );
177 if ( cpwd == "x" && spw )
178 cpwd = QString::fromLocal8Bit( spw->sp_pwdp );
179
180 QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) );
181 return cpwd == cpassword;
182*/
183}
184
185bool ServerPI::checkReadFile( const QString& file ) 273bool ServerPI::checkReadFile( const QString& file )
186{ 274{
187 QString filename; 275 QString filename;
188 276
189 if ( file[0] != "/" ) 277 if ( file[0] != "/" )
190 filename = directory.path() + "/" + file; 278 filename = directory.path() + "/" + file;
191 else 279 else
192 filename = file; 280 filename = file;
193 281
194 QFileInfo fi( filename ); 282 QFileInfo fi( filename );
195 return ( fi.exists() && fi.isReadable() ); 283 return ( fi.exists() && fi.isReadable() );
196} 284}
197 285
198bool ServerPI::checkWriteFile( const QString& file ) 286bool ServerPI::checkWriteFile( const QString& file )
199{ 287{
200 QString filename; 288 QString filename;
201 289
202 if ( file[0] != "/" ) 290 if ( file[0] != "/" )
203 filename = directory.path() + "/" + file; 291 filename = directory.path() + "/" + file;
204 else 292 else
205 filename = file; 293 filename = file;
206 294
207 QFileInfo fi( filename ); 295 QFileInfo fi( filename );
208 296
209 if ( fi.exists() ) 297 if ( fi.exists() )
210 if ( !QFile( filename ).remove() ) 298 if ( !QFile( filename ).remove() )
211 return FALSE; 299 return FALSE;
212 return TRUE; 300 return TRUE;
213} 301}
214 302
215void ServerPI::process( const QString& message ) 303void ServerPI::process( const QString& message )
216{ 304{
@@ -225,78 +313,77 @@ void ServerPI::process( const QString& message )
225 313
226 // argument token 314 // argument token
227 QString arg; 315 QString arg;
228 if ( msg.count() >= 2 ) 316 if ( msg.count() >= 2 )
229 arg = msg[1]; 317 arg = msg[1];
230 318
231 // full argument string 319 // full argument string
232 QString args; 320 QString args;
233 if ( msg.count() >= 2 ) { 321 if ( msg.count() >= 2 ) {
234 QStringList copy( msg ); 322 QStringList copy( msg );
235 // FIXME: for Qt3 323 // FIXME: for Qt3
236 // copy.pop_front() 324 // copy.pop_front()
237 copy.remove( copy.begin() ); 325 copy.remove( copy.begin() );
238 args = copy.join( " " ); 326 args = copy.join( " " );
239 } 327 }
240 328
241 //qDebug( "args: %s", args.latin1() ); 329 //qDebug( "args: %s", args.latin1() );
242 330
243 // we always respond to QUIT, regardless of state 331 // we always respond to QUIT, regardless of state
244 if ( cmd == "QUIT" ) { 332 if ( cmd == "QUIT" ) {
245 send( "211 Good bye!" ); 333 send( "211 Good bye!" );
246 delete this; 334 delete this;
247 return; 335 return;
248 } 336 }
249 337
250 // connected to client 338 // connected to client
251 if ( Connected == state ) 339 if ( Connected == state )
252 return; 340 return;
253 341
254 // waiting for user name 342 // waiting for user name
255 if ( Wait_USER == state ) { 343 if ( Wait_USER == state ) {
256 344
257 if ( cmd != "USER" || msg.count() < 2 || !checkUser( arg ) ) { 345 if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) {
258 send( "530 Please login with USER and PASS" ); 346 send( "530 Please login with USER and PASS" );
259 return; 347 return;
260 } 348 }
261 send( "331 User name ok, need password" ); 349 send( "331 User name ok, need password" );
262 state = Wait_PASS; 350 state = Wait_PASS;
263 return; 351 return;
264 } 352 }
265 353
266 // waiting for password 354 // waiting for password
267 if ( Wait_PASS == state ) { 355 if ( Wait_PASS == state ) {
268 356
269 if ( cmd != "PASS" || !checkPassword( arg ) ) { 357 if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) {
270 //if ( cmd != "PASS" || msg.count() < 2 || !checkPassword( arg ) ) {
271 send( "530 Please login with USER and PASS" ); 358 send( "530 Please login with USER and PASS" );
272 return; 359 return;
273 } 360 }
274 send( "230 User logged in, proceed" ); 361 send( "230 User logged in, proceed" );
275 state = Ready; 362 state = Ready;
276 return; 363 return;
277 } 364 }
278 365
279 // ACCESS CONTROL COMMANDS 366 // ACCESS CONTROL COMMANDS
280 367
281 368
282 // account (ACCT) 369 // account (ACCT)
283 if ( cmd == "ACCT" ) { 370 if ( cmd == "ACCT" ) {
284 // even wu-ftp does not support it 371 // even wu-ftp does not support it
285 send( "502 Command not implemented" ); 372 send( "502 Command not implemented" );
286 } 373 }
287 374
288 // change working directory (CWD) 375 // change working directory (CWD)
289 else if ( cmd == "CWD" ) { 376 else if ( cmd == "CWD" ) {
290 377
291 if ( !args.isEmpty() ) { 378 if ( !args.isEmpty() ) {
292 if ( directory.cd( args, TRUE ) ) 379 if ( directory.cd( args, TRUE ) )
293 send( "250 Requested file action okay, completed" ); 380 send( "250 Requested file action okay, completed" );
294 else 381 else
295 send( "550 Requested action not taken" ); 382 send( "550 Requested action not taken" );
296 } 383 }
297 else 384 else
298 send( "500 Syntax error, command unrecognized" ); 385 send( "500 Syntax error, command unrecognized" );
299 } 386 }
300 387
301 // change to parent directory (CDUP) 388 // change to parent directory (CDUP)
302 else if ( cmd == "CDUP" ) { 389 else if ( cmd == "CDUP" ) {
@@ -425,68 +512,71 @@ void ServerPI::process( const QString& message )
425 } 512 }
426 513
427 // rename to (RNTO) 514 // rename to (RNTO)
428 else if ( cmd == "RNTO" ) { 515 else if ( cmd == "RNTO" ) {
429 if ( lastCommand != "RNFR" ) 516 if ( lastCommand != "RNFR" )
430 send( "503 Bad sequence of commands" ); 517 send( "503 Bad sequence of commands" );
431 else if ( args.isEmpty() ) 518 else if ( args.isEmpty() )
432 send( "500 Syntax error, command unrecognized" ); 519 send( "500 Syntax error, command unrecognized" );
433 else { 520 else {
434 QDir dir( absFilePath( args ) ); 521 QDir dir( absFilePath( args ) );
435 if ( dir.rename( renameFrom, absFilePath( args ), TRUE ) ) 522 if ( dir.rename( renameFrom, absFilePath( args ), TRUE ) )
436 send( "250 Requested file action okay, completed." ); 523 send( "250 Requested file action okay, completed." );
437 else 524 else
438 send( "550 Requested action not taken" ); 525 send( "550 Requested action not taken" );
439 } 526 }
440 } 527 }
441 528
442 // abort (ABOR) 529 // abort (ABOR)
443 else if ( cmd.contains( "ABOR" ) ) { 530 else if ( cmd.contains( "ABOR" ) ) {
444 dtp->close(); 531 dtp->close();
445 if ( dtp->dtpMode() != ServerDTP::Idle ) 532 if ( dtp->dtpMode() != ServerDTP::Idle )
446 send( "426 Connection closed; transfer aborted" ); 533 send( "426 Connection closed; transfer aborted" );
447 else 534 else
448 send( "226 Closing data connection" ); 535 send( "226 Closing data connection" );
449 } 536 }
450 537
451 // delete (DELE) 538 // delete (DELE)
452 else if ( cmd == "DELE" ) { 539 else if ( cmd == "DELE" ) {
453 if ( args.isEmpty() ) 540 if ( args.isEmpty() )
454 send( "500 Syntax error, command unrecognized" ); 541 send( "500 Syntax error, command unrecognized" );
455 else { 542 else {
456 QFile file( absFilePath( args ) ) ; 543 QFile file( absFilePath( args ) ) ;
457 if ( file.remove() ) 544 if ( file.remove() ) {
458 send( "250 Requested file action okay, completed" ); 545 send( "250 Requested file action okay, completed" );
459 else 546 QCopEnvelope e("QPE/System", "linkChanged(QString)" );
547 e << file.name();
548 } else {
460 send( "550 Requested action not taken" ); 549 send( "550 Requested action not taken" );
550 }
461 } 551 }
462 } 552 }
463 553
464 // remove directory (RMD) 554 // remove directory (RMD)
465 else if ( cmd == "RMD" ) { 555 else if ( cmd == "RMD" ) {
466 if ( args.isEmpty() ) 556 if ( args.isEmpty() )
467 send( "500 Syntax error, command unrecognized" ); 557 send( "500 Syntax error, command unrecognized" );
468 else { 558 else {
469 QDir dir; 559 QDir dir;
470 if ( dir.rmdir( absFilePath( args ), TRUE ) ) 560 if ( dir.rmdir( absFilePath( args ), TRUE ) )
471 send( "250 Requested file action okay, completed" ); 561 send( "250 Requested file action okay, completed" );
472 else 562 else
473 send( "550 Requested action not taken" ); 563 send( "550 Requested action not taken" );
474 } 564 }
475 } 565 }
476 566
477 // make directory (MKD) 567 // make directory (MKD)
478 else if ( cmd == "MKD" ) { 568 else if ( cmd == "MKD" ) {
479 if ( args.isEmpty() ) { 569 if ( args.isEmpty() ) {
480 qDebug(" Error: no arg"); 570 qDebug(" Error: no arg");
481 send( "500 Syntax error, command unrecognized" ); 571 send( "500 Syntax error, command unrecognized" );
482 } 572 }
483 else { 573 else {
484 QDir dir; 574 QDir dir;
485 if ( dir.mkdir( absFilePath( args ), TRUE ) ) 575 if ( dir.mkdir( absFilePath( args ), TRUE ) )
486 send( "250 Requested file action okay, completed." ); 576 send( "250 Requested file action okay, completed." );
487 else 577 else
488 send( "550 Requested action not taken" ); 578 send( "550 Requested action not taken" );
489 } 579 }
490 } 580 }
491 581
492 // print working directory (PWD) 582 // print working directory (PWD)
@@ -605,67 +695,74 @@ void ServerPI::sendFile( const QString& file )
605 695
606void ServerPI::retrieveFile( const QString& file ) 696void ServerPI::retrieveFile( const QString& file )
607{ 697{
608 if ( passiv ) { 698 if ( passiv ) {
609 wait[RetrieveFile] = TRUE; 699 wait[RetrieveFile] = TRUE;
610 waitfile = file; 700 waitfile = file;
611 if ( waitsocket ) 701 if ( waitsocket )
612 newConnection( waitsocket ); 702 newConnection( waitsocket );
613 } 703 }
614 else { 704 else {
615 QStringList targets; 705 QStringList targets;
616 if ( backupRestoreGzip( file, targets ) ) 706 if ( backupRestoreGzip( file, targets ) )
617 dtp->retrieveGzipFile( file, peeraddress, peerport ); 707 dtp->retrieveGzipFile( file, peeraddress, peerport );
618 else 708 else
619 dtp->retrieveFile( file, peeraddress, peerport ); 709 dtp->retrieveFile( file, peeraddress, peerport );
620 } 710 }
621} 711}
622 712
623bool ServerPI::parsePort( const QString& pp ) 713bool ServerPI::parsePort( const QString& pp )
624{ 714{
625 QStringList p = QStringList::split( ",", pp ); 715 QStringList p = QStringList::split( ",", pp );
626 if ( p.count() != 6 ) return FALSE; 716 if ( p.count() != 6 ) return FALSE;
627 717
628 // h1,h2,h3,h4,p1,p2 718 // h1,h2,h3,h4,p1,p2
629 peeraddress = QHostAddress( ( p[0].toInt() << 24 ) + ( p[1].toInt() << 16 ) + 719 peeraddress = QHostAddress( ( p[0].toInt() << 24 ) + ( p[1].toInt() << 16 ) +
630 ( p[2].toInt() << 8 ) + p[3].toInt() ); 720 ( p[2].toInt() << 8 ) + p[3].toInt() );
631 peerport = ( p[4].toInt() << 8 ) + p[5].toInt(); 721 peerport = ( p[4].toInt() << 8 ) + p[5].toInt();
632 return TRUE; 722 return TRUE;
633} 723}
634 724
635void ServerPI::dtpCompleted() 725void ServerPI::dtpCompleted()
636{ 726{
637 dtp->close();
638 waitsocket = 0;
639 send( "226 Closing data connection, file transfer successful" ); 727 send( "226 Closing data connection, file transfer successful" );
728 if ( dtp->dtpMode() == ServerDTP::RetrieveFile ) {
729 QString fn = dtp->fileName();
730 if ( fn.right(8)==".desktop" && fn.find("/Documents/")>=0 ) {
731 QCopEnvelope e("QPE/System", "linkChanged(QString)" );
732 e << fn;
733 }
734 }
735 waitsocket = 0;
736 dtp->close();
640} 737}
641 738
642void ServerPI::dtpFailed() 739void ServerPI::dtpFailed()
643{ 740{
644 dtp->close(); 741 dtp->close();
645 waitsocket = 0; 742 waitsocket = 0;
646 send( "451 Requested action aborted: local error in processing" ); 743 send( "451 Requested action aborted: local error in processing" );
647} 744}
648 745
649void ServerPI::dtpError( int ) 746void ServerPI::dtpError( int )
650{ 747{
651 dtp->close(); 748 dtp->close();
652 waitsocket = 0; 749 waitsocket = 0;
653 send( "451 Requested action aborted: local error in processing" ); 750 send( "451 Requested action aborted: local error in processing" );
654} 751}
655 752
656bool ServerPI::sendList( const QString& arg ) 753bool ServerPI::sendList( const QString& arg )
657{ 754{
658 QByteArray listing; 755 QByteArray listing;
659 QBuffer buffer( listing ); 756 QBuffer buffer( listing );
660 757
661 if ( !buffer.open( IO_WriteOnly ) ) 758 if ( !buffer.open( IO_WriteOnly ) )
662 return FALSE; 759 return FALSE;
663 760
664 QTextStream ts( &buffer ); 761 QTextStream ts( &buffer );
665 QString fn = arg; 762 QString fn = arg;
666 763
667 if ( fn.isEmpty() ) 764 if ( fn.isEmpty() )
668 fn = directory.path(); 765 fn = directory.path();
669 766
670 QFileInfo fi( fn ); 767 QFileInfo fi( fn );
671 if ( !fi.exists() ) return FALSE; 768 if ( !fi.exists() ) return FALSE;
@@ -823,105 +920,107 @@ void ServerPI::newConnection( int socket )
823 dtp->setSocket( socket ); 920 dtp->setSocket( socket );
824 } 921 }
825 else if ( wait[RetrieveByteArray] ) { 922 else if ( wait[RetrieveByteArray] ) {
826 qDebug("retrieve byte array"); 923 qDebug("retrieve byte array");
827 dtp->retrieveByteArray(); 924 dtp->retrieveByteArray();
828 dtp->setSocket( socket ); 925 dtp->setSocket( socket );
829 } 926 }
830 else 927 else
831 waitsocket = socket; 928 waitsocket = socket;
832 929
833 for( int i = 0; i < 4; i++ ) 930 for( int i = 0; i < 4; i++ )
834 wait[i] = FALSE; 931 wait[i] = FALSE;
835} 932}
836 933
837QString ServerPI::absFilePath( const QString& file ) 934QString ServerPI::absFilePath( const QString& file )
838{ 935{
839 if ( file.isEmpty() ) return file; 936 if ( file.isEmpty() ) return file;
840 937
841 QString filepath( file ); 938 QString filepath( file );
842 if ( file[0] != "/" ) 939 if ( file[0] != "/" )
843 filepath = directory.path() + "/" + file; 940 filepath = directory.path() + "/" + file;
844 941
845 return filepath; 942 return filepath;
846} 943}
847 944
848 945
849void ServerPI::timerEvent( QTimerEvent * ) 946void ServerPI::timerEvent( QTimerEvent * )
850{ 947{
851 connectionClosed(); 948 connectionClosed();
852} 949}
853 950
854 951
855ServerDTP::ServerDTP( QObject *parent, const char* name ) 952ServerDTP::ServerDTP( QObject *parent = 0, const char* name = 0)
856 : QSocket( parent, name ), mode( Idle ), createTargzProc( 0 ), 953 : QSocket( parent, name ), mode( Idle ), createTargzProc( 0 ),
857retrieveTargzProc( 0 ), gzipProc( 0 ) 954retrieveTargzProc( 0 ), gzipProc( 0 )
858{ 955{
859 956
860 connect( this, SIGNAL( connected() ), SLOT( connected() ) ); 957 connect( this, SIGNAL( connected() ), SLOT( connected() ) );
861 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); 958 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
862 connect( this, SIGNAL( bytesWritten( int ) ), SLOT( bytesWritten( int ) ) ); 959 connect( this, SIGNAL( bytesWritten( int ) ), SLOT( bytesWritten( int ) ) );
863 connect( this, SIGNAL( readyRead() ), SLOT( readyRead() ) ); 960 connect( this, SIGNAL( readyRead() ), SLOT( readyRead() ) );
864 961
865 gzipProc = new QProcess( this, "gzipProc" ); 962 gzipProc = new QProcess( this, "gzipProc" );
866 gzipProc->setCommunication( QProcess::Stdin | QProcess::Stdout ); 963 gzipProc->setCommunication( QProcess::Stdin | QProcess::Stdout );
867 964
868 createTargzProc = new QProcess( QString("tar"), this, "createTargzProc"); 965 createTargzProc = new QProcess( QString("tar"), this, "createTargzProc");
869 createTargzProc->setCommunication( QProcess::Stdout ); 966 createTargzProc->setCommunication( QProcess::Stdout );
870 createTargzProc->setWorkingDirectory( QDir::rootDirPath() ); 967 createTargzProc->setWorkingDirectory( QDir::rootDirPath() );
871 connect( createTargzProc, SIGNAL( processExited() ), SLOT( targzDone() ) ); 968 connect( createTargzProc, SIGNAL( processExited() ), SLOT( targzDone() ) );
872 969
873 QStringList args = "tar"; 970 QStringList args = "tar";
874 args += "-xv"; 971 args += "-xv";
875 retrieveTargzProc = new QProcess( args, this, "retrieveTargzProc" ); 972 retrieveTargzProc = new QProcess( args, this, "retrieveTargzProc" );
876 retrieveTargzProc->setCommunication( QProcess::Stdin ); 973 retrieveTargzProc->setCommunication( QProcess::Stdin );
877 retrieveTargzProc->setWorkingDirectory( QDir::rootDirPath() ); 974 retrieveTargzProc->setWorkingDirectory( QDir::rootDirPath() );
878 connect( retrieveTargzProc, SIGNAL( processExited() ), 975 connect( retrieveTargzProc, SIGNAL( processExited() ),
879 SIGNAL( completed() ) ); 976 SIGNAL( completed() ) );
880 connect( retrieveTargzProc, SIGNAL( processExited() ), 977 connect( retrieveTargzProc, SIGNAL( processExited() ),
881 SLOT( extractTarDone() ) ); 978 SLOT( extractTarDone() ) );
882} 979}
883 980
884ServerDTP::~ServerDTP() 981ServerDTP::~ServerDTP()
885{ 982{
886 buf.close(); 983 buf.close();
887 file.close(); 984 file.close();
888 createTargzProc->kill(); 985 createTargzProc->kill();
889} 986}
890 987
891void ServerDTP::extractTarDone() 988void ServerDTP::extractTarDone()
892{ 989{
893 qDebug("extract done"); 990 qDebug("extract done");
991#ifndef QT_NO_COP
894 QCopEnvelope e( "QPE/Desktop", "restoreDone(QString)" ); 992 QCopEnvelope e( "QPE/Desktop", "restoreDone(QString)" );
895 e << file.name(); 993 e << file.name();
994#endif
896} 995}
897 996
898void ServerDTP::connected() 997void ServerDTP::connected()
899{ 998{
900 // send file mode 999 // send file mode
901 switch ( mode ) { 1000 switch ( mode ) {
902 case SendFile : 1001 case SendFile :
903 if ( !file.exists() || !file.open( IO_ReadOnly) ) { 1002 if ( !file.exists() || !file.open( IO_ReadOnly) ) {
904 emit failed(); 1003 emit failed();
905 mode = Idle; 1004 mode = Idle;
906 return; 1005 return;
907 } 1006 }
908 1007
909 //qDebug( "Debug: Sending file '%s'", file.name().latin1() ); 1008 //qDebug( "Debug: Sending file '%s'", file.name().latin1() );
910 1009
911 bytes_written = 0; 1010 bytes_written = 0;
912 if ( file.size() == 0 ) { 1011 if ( file.size() == 0 ) {
913 //make sure it doesn't hang on empty files 1012 //make sure it doesn't hang on empty files
914 file.close(); 1013 file.close();
915 emit completed(); 1014 emit completed();
916 mode = Idle; 1015 mode = Idle;
917 } else { 1016 } else {
918 1017
919 if( !file.atEnd() ) { 1018 if( !file.atEnd() ) {
920 QCString s; 1019 QCString s;
921 s.resize( block_size ); 1020 s.resize( block_size );
922 int bytes = file.readBlock( s.data(), block_size ); 1021 int bytes = file.readBlock( s.data(), block_size );
923 writeBlock( s.data(), bytes ); 1022 writeBlock( s.data(), bytes );
924 } 1023 }
925 } 1024 }
926 break; 1025 break;
927 case SendGzipFile: 1026 case SendGzipFile:
diff --git a/core/launcher/transferserver.h b/core/launcher/transferserver.h
index 076e460..a3bb060 100644
--- a/core/launcher/transferserver.h
+++ b/core/launcher/transferserver.h
@@ -1,99 +1,114 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of 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 <qserversocket.h> 20#include <qserversocket.h>
21#include <qsocket.h> 21#include <qsocket.h>
22#include <qdir.h> 22#include <qdir.h>
23#include <qfile.h> 23#include <qfile.h>
24#include <qbuffer.h> 24#include <qbuffer.h>
25 25
26class QFileInfo; 26class QFileInfo;
27class QProcess; 27class QProcess;
28class TransferServer : public QServerSocket 28class TransferServer : public QServerSocket
29{ 29{
30 Q_OBJECT 30 Q_OBJECT
31 31
32public: 32public:
33 TransferServer( Q_UINT16 port, QObject *parent = 0, const char* name = 0 ); 33 TransferServer( Q_UINT16 port, QObject *parent = 0, const char* name = 0 );
34 virtual ~TransferServer(); 34 virtual ~TransferServer();
35 35
36 void newConnection( int socket ); 36 void newConnection( int socket );
37}; 37};
38 38
39class SyncAuthentication : QObject
40{
41 Q_OBJECT
42
43public:
44 static int isAuthorized(QHostAddress peeraddress);
45 static bool checkPassword(const QString& pw);
46 static bool checkUser(const QString& user);
47
48 static QString serverId();
49 static QString loginName();
50 static QString ownerName();
51};
52
39 53
40class ServerDTP : public QSocket 54class ServerDTP : public QSocket
41{ 55{
42 Q_OBJECT 56 Q_OBJECT
43 57
44public: 58public:
45 ServerDTP( QObject *parent = 0, const char* name = 0 ); 59 ServerDTP( QObject *parent = 0, const char* name = 0 );
46 ~ServerDTP(); 60 ~ServerDTP();
47 61
48 enum Mode{ Idle = 0, SendFile, SendGzipFile, SendBuffer, 62 enum Mode{ Idle = 0, SendFile, SendGzipFile, SendBuffer,
49 RetrieveFile, RetrieveGzipFile, RetrieveBuffer }; 63 RetrieveFile, RetrieveGzipFile, RetrieveBuffer };
50 64
51 void sendFile( const QString fn ); 65 void sendFile( const QString fn );
52 void sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port ); 66 void sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port );
53 void sendGzipFile( const QString &fn, const QStringList &archiveTargets ); 67 void sendGzipFile( const QString &fn, const QStringList &archiveTargets );
54 void sendGzipFile( const QString &fn, const QStringList &archiveTargets, 68 void sendGzipFile( const QString &fn, const QStringList &archiveTargets,
55 const QHostAddress& host, Q_UINT16 port ); 69 const QHostAddress& host, Q_UINT16 port );
56 void sendByteArray( const QByteArray& array ); 70 void sendByteArray( const QByteArray& array );
57 void sendByteArray( const QByteArray& array, const QHostAddress& host, Q_UINT16 port ); 71 void sendByteArray( const QByteArray& array, const QHostAddress& host, Q_UINT16 port );
58 72
59 void retrieveFile( const QString fn ); 73 void retrieveFile( const QString fn );
60 void retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port ); 74 void retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port );
61 void retrieveGzipFile( const QString &fn ); 75 void retrieveGzipFile( const QString &fn );
62 void retrieveGzipFile( const QString &fn, const QHostAddress& host, Q_UINT16 port ); 76 void retrieveGzipFile( const QString &fn, const QHostAddress& host, Q_UINT16 port );
63 void retrieveByteArray(); 77 void retrieveByteArray();
64 void retrieveByteArray( const QHostAddress& host, Q_UINT16 port ); 78 void retrieveByteArray( const QHostAddress& host, Q_UINT16 port );
65 79
66 Mode dtpMode() { return mode; } 80 Mode dtpMode() { return mode; }
67 QByteArray buffer() { return buf.buffer(); } 81 QByteArray buffer() { return buf.buffer(); }
82 QString fileName() const { return file.name(); }
68 83
69 void setSocket( int socket ); 84 void setSocket( int socket );
70 85
71signals: 86signals:
72 void completed(); 87 void completed();
73 void failed(); 88 void failed();
74 89
75private slots: 90private slots:
76 void connectionClosed(); 91 void connectionClosed();
77 void connected(); 92 void connected();
78 void bytesWritten( int bytes ); 93 void bytesWritten( int bytes );
79 void readyRead(); 94 void readyRead();
80 void writeTargzBlock(); 95 void writeTargzBlock();
81 void targzDone(); 96 void targzDone();
82 97
83 void gzipTarBlock(); 98 void gzipTarBlock();
84 void tarExtractBlock(); 99 void tarExtractBlock();
85 void gunzipDone(); 100 void gunzipDone();
86 void extractTarDone(); 101 void extractTarDone();
87 102
88private: 103private:
89 104
90 unsigned long bytes_written; 105 unsigned long bytes_written;
91 Mode mode; 106 Mode mode;
92 QFile file; 107 QFile file;
93 QBuffer buf; 108 QBuffer buf;
94 QProcess *createTargzProc; 109 QProcess *createTargzProc;
95 QProcess *retrieveTargzProc; 110 QProcess *retrieveTargzProc;
96 QProcess *gzipProc; 111 QProcess *gzipProc;
97}; 112};
98 113
99class ServerSocket : public QServerSocket 114class ServerSocket : public QServerSocket
@@ -102,67 +117,63 @@ class ServerSocket : public QServerSocket
102 117
103public: 118public:
104 ServerSocket( Q_UINT16 port, QObject *parent = 0, const char* name = 0 ) 119 ServerSocket( Q_UINT16 port, QObject *parent = 0, const char* name = 0 )
105 : QServerSocket( port, 1, parent, name ) {} 120 : QServerSocket( port, 1, parent, name ) {}
106 121
107 void newConnection( int socket ) { emit newIncomming( socket ); } 122 void newConnection( int socket ) { emit newIncomming( socket ); }
108signals: 123signals:
109 void newIncomming( int socket ); 124 void newIncomming( int socket );
110}; 125};
111 126
112class ServerPI : public QSocket 127class ServerPI : public QSocket
113{ 128{
114 Q_OBJECT 129 Q_OBJECT
115 130
116 enum State { Connected, Wait_USER, Wait_PASS, Ready, Forbidden }; 131 enum State { Connected, Wait_USER, Wait_PASS, Ready, Forbidden };
117 enum Transfer { SendFile = 0, RetrieveFile = 1, SendByteArray = 2, RetrieveByteArray = 3 }; 132 enum Transfer { SendFile = 0, RetrieveFile = 1, SendByteArray = 2, RetrieveByteArray = 3 };
118 133
119public: 134public:
120 ServerPI( int socket, QObject *parent = 0, const char* name = 0 ); 135 ServerPI( int socket, QObject *parent = 0, const char* name = 0 );
121 virtual ~ServerPI(); 136 virtual ~ServerPI();
122 137
123protected slots: 138protected slots:
124 void read(); 139 void read();
125 void send( const QString& msg ); 140 void send( const QString& msg );
126 void process( const QString& command ); 141 void process( const QString& command );
127 void connectionClosed(); 142 void connectionClosed();
128 void dtpCompleted(); 143 void dtpCompleted();
129 void dtpFailed(); 144 void dtpFailed();
130 void dtpError( int ); 145 void dtpError( int );
131 void newConnection( int socket ); 146 void newConnection( int socket );
132 147
133protected: 148protected:
134 bool checkUser( const QString& user );
135 bool checkPassword( const QString& pw );
136 bool checkReadFile( const QString& file ); 149 bool checkReadFile( const QString& file );
137 bool checkWriteFile( const QString& file ); 150 bool checkWriteFile( const QString& file );
138 bool parsePort( const QString& pw ); 151 bool parsePort( const QString& pw );
139 bool backupRestoreGzip( const QString &file, QStringList &targets ); 152 bool backupRestoreGzip( const QString &file, QStringList &targets );
140 bool backupRestoreGzip( const QString &file ); 153 bool backupRestoreGzip( const QString &file );
141 154
142 bool sendList( const QString& arg ); 155 bool sendList( const QString& arg );
143 void sendFile( const QString& file ); 156 void sendFile( const QString& file );
144 void retrieveFile( const QString& file ); 157 void retrieveFile( const QString& file );
145 158
146 QString permissionString( QFileInfo *info ); 159 QString permissionString( QFileInfo *info );
147 QString fileListing( QFileInfo *info ); 160 QString fileListing( QFileInfo *info );
148 QString absFilePath( const QString& file ); 161 QString absFilePath( const QString& file );
149 162
150 void timerEvent( QTimerEvent *e ); 163 void timerEvent( QTimerEvent *e );
151 164
152private: 165private:
153 State state; 166 State state;
154 Q_UINT16 peerport; 167 Q_UINT16 peerport;
155 QHostAddress peeraddress; 168 QHostAddress peeraddress;
156 bool passiv; 169 bool passiv;
157 bool wait[4]; 170 bool wait[4];
158 ServerDTP *dtp; 171 ServerDTP *dtp;
159 ServerSocket *serversocket; 172 ServerSocket *serversocket;
160 QString waitfile; 173 QString waitfile;
161 QDir directory; 174 QDir directory;
162 QByteArray waitarray; 175 QByteArray waitarray;
163 QString renameFrom; 176 QString renameFrom;
164 QString lastCommand; 177 QString lastCommand;
165 int waitsocket; 178 int waitsocket;
166}; 179};
167
168bool accessAuthorized(QHostAddress peeraddress);