KHTML
kjavaappletserver.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE project 00002 * 00003 * Copyright (C) 2000 Richard Moore <rich@kde.org> 00004 * 2000 Wynn Wilkes <wynnw@caldera.com> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Library General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Library General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Library General Public License 00017 * along with this library; see the file COPYING.LIB. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include "kjavaappletserver.h" 00023 00024 #include "kjavaappletcontext.h" 00025 #include "kjavaprocess.h" 00026 #include "kjavadownloader.h" 00027 00028 #include <config.h> 00029 00030 #include <kdebug.h> 00031 #include <kconfig.h> 00032 #include <kconfiggroup.h> 00033 #include <klocale.h> 00034 #include <kparts/browserextension.h> 00035 #include <kstandarddirs.h> 00036 00037 #include <kio/job.h> 00038 #include <kio/kprotocolmanager.h> 00039 #include <ksslcertificate.h> 00040 #include <ksslcertchain.h> 00041 #include <kssl.h> 00042 00043 #include <QtCore/QTimer> 00044 #include <QtCore/QPointer> 00045 #include <QtCore/QDir> 00046 #include <QtCore/QEventLoop> 00047 #include <QtGui/QApplication> 00048 #include <QtGui/QLabel> 00049 #include <QtGui/QDialog> 00050 #include <QtGui/QPushButton> 00051 #include <QtGui/QLayout> 00052 #include <QtCore/QRegExp> 00053 00054 #include <stdlib.h> 00055 #include <assert.h> 00056 #include <QtCore/QAbstractEventDispatcher> 00057 00058 #define KJAS_CREATE_CONTEXT (char)1 00059 #define KJAS_DESTROY_CONTEXT (char)2 00060 #define KJAS_CREATE_APPLET (char)3 00061 #define KJAS_DESTROY_APPLET (char)4 00062 #define KJAS_START_APPLET (char)5 00063 #define KJAS_STOP_APPLET (char)6 00064 #define KJAS_INIT_APPLET (char)7 00065 #define KJAS_SHOW_DOCUMENT (char)8 00066 #define KJAS_SHOW_URLINFRAME (char)9 00067 #define KJAS_SHOW_STATUS (char)10 00068 #define KJAS_RESIZE_APPLET (char)11 00069 #define KJAS_GET_URLDATA (char)12 00070 #define KJAS_URLDATA (char)13 00071 #define KJAS_SHUTDOWN_SERVER (char)14 00072 #define KJAS_JAVASCRIPT_EVENT (char)15 00073 #define KJAS_GET_MEMBER (char)16 00074 #define KJAS_CALL_MEMBER (char)17 00075 #define KJAS_PUT_MEMBER (char)18 00076 #define KJAS_DEREF_OBJECT (char)19 00077 #define KJAS_AUDIOCLIP_PLAY (char)20 00078 #define KJAS_AUDIOCLIP_LOOP (char)21 00079 #define KJAS_AUDIOCLIP_STOP (char)22 00080 #define KJAS_APPLET_STATE (char)23 00081 #define KJAS_APPLET_FAILED (char)24 00082 #define KJAS_DATA_COMMAND (char)25 00083 #define KJAS_PUT_URLDATA (char)26 00084 #define KJAS_PUT_DATA (char)27 00085 #define KJAS_SECURITY_CONFIRM (char)28 00086 #define KJAS_SHOW_CONSOLE (char)29 00087 00088 00089 class JSStackFrame; 00090 00091 typedef QMap< int, KJavaKIOJob* > KIOJobMap; 00092 typedef QMap< int, JSStackFrame* > JSStack; 00093 00094 class JSStackFrame { 00095 public: 00096 JSStackFrame(JSStack & stack, QStringList & a) 00097 : jsstack(stack), args(a), ticket(counter++), ready(false), exit (false) { 00098 jsstack.insert( ticket, this ); 00099 } 00100 ~JSStackFrame() { 00101 jsstack.remove( ticket ); 00102 } 00103 JSStack & jsstack; 00104 QStringList & args; 00105 int ticket; 00106 bool ready : 1; 00107 bool exit : 1; 00108 static int counter; 00109 }; 00110 00111 int JSStackFrame::counter = 0; 00112 00113 class KJavaAppletServerPrivate 00114 { 00115 friend class KJavaAppletServer; 00116 private: 00117 KJavaAppletServerPrivate() : kssl( 0L ) {} 00118 ~KJavaAppletServerPrivate() { 00119 delete kssl; 00120 } 00121 int counter; 00122 QMap< int, QPointer<KJavaAppletContext> > contexts; 00123 QString appletLabel; 00124 JSStack jsstack; 00125 KIOJobMap kiojobs; 00126 bool javaProcessFailed; 00127 bool useKIO; 00128 KSSL * kssl; 00129 //int locked_context; 00130 //QValueList<QByteArray> java_requests; 00131 }; 00132 00133 static KJavaAppletServer* self = 0; 00134 00135 KJavaAppletServer::KJavaAppletServer() 00136 : d(new KJavaAppletServerPrivate) 00137 { 00138 process = new KJavaProcess(); 00139 00140 connect( process, SIGNAL(received(QByteArray)), 00141 this, SLOT(slotJavaRequest(QByteArray)) ); 00142 00143 setupJava( process ); 00144 00145 if( process->startJava() ) { 00146 d->appletLabel = i18n( "Loading Applet" ); 00147 d->javaProcessFailed = false; 00148 } 00149 else { 00150 d->appletLabel = i18n( "Error: java executable not found" ); 00151 d->javaProcessFailed = true; 00152 } 00153 } 00154 00155 KJavaAppletServer::~KJavaAppletServer() 00156 { 00157 disconnect(process, 0, 0, 0); // first disconnect from process. 00158 quit(); 00159 00160 delete process; 00161 process = 0; 00162 delete d; 00163 } 00164 00165 QString KJavaAppletServer::getAppletLabel() 00166 { 00167 if( self ) 00168 return self->appletLabel(); 00169 else 00170 return QString(); 00171 } 00172 00173 QString KJavaAppletServer::appletLabel() 00174 { 00175 return d->appletLabel; 00176 } 00177 00178 KJavaAppletServer* KJavaAppletServer::allocateJavaServer() 00179 { 00180 if( self == 0 ) 00181 { 00182 self = new KJavaAppletServer(); 00183 self->d->counter = 0; 00184 } 00185 00186 ++(self->d->counter); 00187 return self; 00188 } 00189 00190 void KJavaAppletServer::freeJavaServer() 00191 { 00192 --(self->d->counter); 00193 00194 if( self->d->counter == 0 ) 00195 { 00196 //instead of immediately quitting here, set a timer to kill us 00197 //if there are still no servers- give us one minute 00198 //this is to prevent repeated loading and unloading of the jvm 00199 KConfig config( "konquerorrc" ); 00200 KConfigGroup group = config.group( "Java/JavaScript Settings" ); 00201 if( group.readEntry( "ShutdownAppletServer", true ) ) 00202 { 00203 const int value = group.readEntry( "AppletServerTimeout", 60 ); 00204 QTimer::singleShot( value*1000, self, SLOT(checkShutdown()) ); 00205 } 00206 } 00207 } 00208 00209 void KJavaAppletServer::checkShutdown() 00210 { 00211 if( self->d->counter == 0 ) 00212 { 00213 delete self; 00214 self = 0; 00215 } 00216 } 00217 00218 void KJavaAppletServer::setupJava( KJavaProcess *p ) 00219 { 00220 KConfig configFile ( "konquerorrc" ); 00221 KConfigGroup config(&configFile, "Java/JavaScript Settings" ); 00222 00223 QString jvm_path = "java"; 00224 00225 QString jPath = config.readPathEntry( "JavaPath", QString() ); 00226 if ( !jPath.isEmpty() && jPath != "java" ) 00227 { 00228 // Cut off trailing slash if any 00229 if( jPath[jPath.length()-1] == '/' ) 00230 jPath.remove(jPath.length()-1, 1); 00231 00232 QDir dir( jPath ); 00233 if( dir.exists( "bin/java" ) ) 00234 { 00235 jvm_path = jPath + "/bin/java"; 00236 } 00237 else if (dir.exists( "/jre/bin/java" ) ) 00238 { 00239 jvm_path = jPath + "/jre/bin/java"; 00240 } 00241 else if( QFile::exists(jPath) ) 00242 { 00243 //check here to see if they entered the whole path the java exe 00244 jvm_path = jPath; 00245 } 00246 } 00247 00248 //check to see if jvm_path is valid and set d->appletLabel accordingly 00249 p->setJVMPath( jvm_path ); 00250 00251 // Prepare classpath variable 00252 QString kjava_class = KStandardDirs::locate("data", "kjava/kjava.jar"); 00253 kDebug(6100) << "kjava_class = " << kjava_class; 00254 if( kjava_class.isNull() ) // Should not happen 00255 return; 00256 00257 QDir dir( kjava_class ); 00258 dir.cdUp(); 00259 kDebug(6100) << "dir = " << dir.absolutePath(); 00260 00261 const QStringList entries = dir.entryList(QDir::nameFiltersFromString( "*.jar" )); 00262 kDebug(6100) << "entries = " << entries.join( ":" ); 00263 00264 QString classes; 00265 { 00266 QStringList::ConstIterator it = entries.begin(); 00267 const QStringList::ConstIterator itEnd = entries.end(); 00268 for( ; it != itEnd; ++it ) 00269 { 00270 if( !classes.isEmpty() ) 00271 classes += ':'; 00272 classes += dir.absoluteFilePath( *it ); 00273 } 00274 } 00275 p->setClasspath( classes ); 00276 00277 // Fix all the extra arguments 00278 const QString extraArgs = config.readEntry( "JavaArgs" ); 00279 p->setExtraArgs( extraArgs ); 00280 00281 if( config.readEntry( "UseSecurityManager", true ) ) 00282 { 00283 QString class_file = KStandardDirs::locate( "data", "kjava/kjava.policy" ); 00284 p->setSystemProperty( "java.security.policy", class_file ); 00285 00286 p->setSystemProperty( "java.security.manager", 00287 "org.kde.kjas.server.KJASSecurityManager" ); 00288 } 00289 00290 d->useKIO = config.readEntry("UseKio", false); 00291 if( d->useKIO ) 00292 { 00293 p->setSystemProperty( "kjas.useKio", QString() ); 00294 } 00295 00296 //check for http proxies... 00297 if( KProtocolManager::useProxy() ) 00298 { 00299 // only proxyForUrl honors automatic proxy scripts 00300 // we do not know the applet url here so we just use a dummy url 00301 // this is a workaround for now 00302 // FIXME 00303 const KUrl dummyURL( "http://www.kde.org/" ); 00304 const QString httpProxy = KProtocolManager::proxyForUrl(dummyURL); 00305 kDebug(6100) << "httpProxy is " << httpProxy; 00306 00307 const KUrl url( httpProxy ); 00308 p->setSystemProperty( "http.proxyHost", url.host() ); 00309 p->setSystemProperty( "http.proxyPort", QString::number( url.port() ) ); 00310 } 00311 00312 //set the main class to run 00313 p->setMainClass( "org.kde.kjas.server.Main" ); 00314 } 00315 00316 void KJavaAppletServer::createContext( int contextId, KJavaAppletContext* context ) 00317 { 00318 // kDebug(6100) << "createContext: " << contextId; 00319 if ( d->javaProcessFailed ) return; 00320 00321 d->contexts.insert( contextId, context ); 00322 00323 QStringList args; 00324 args.append( QString::number( contextId ) ); 00325 process->send( KJAS_CREATE_CONTEXT, args ); 00326 } 00327 00328 void KJavaAppletServer::destroyContext( int contextId ) 00329 { 00330 // kDebug(6100) << "destroyContext: " << contextId; 00331 if ( d->javaProcessFailed ) return; 00332 d->contexts.remove( contextId ); 00333 00334 QStringList args; 00335 args.append( QString::number( contextId ) ); 00336 process->send( KJAS_DESTROY_CONTEXT, args ); 00337 } 00338 00339 bool KJavaAppletServer::createApplet( int contextId, int appletId, 00340 const QString & name, const QString & clazzName, 00341 const QString & baseURL, const QString & user, 00342 const QString & password, const QString & authname, 00343 const QString & codeBase, const QString & jarFile, 00344 QSize size, const QMap<QString,QString>& params, 00345 const QString & windowTitle ) 00346 { 00347 // kDebug(6100) << "createApplet: contextId = " << contextId << endl 00348 // << " appletId = " << appletId << endl 00349 // << " name = " << name << endl 00350 // << " clazzName = " << clazzName << endl 00351 // << " baseURL = " << baseURL << endl 00352 // << " codeBase = " << codeBase << endl 00353 // << " jarFile = " << jarFile << endl 00354 // << " width = " << size.width() << endl 00355 // << " height = " << size.height() << endl; 00356 00357 if ( d->javaProcessFailed ) return false; 00358 00359 QStringList args; 00360 args.append( QString::number( contextId ) ); 00361 args.append( QString::number( appletId ) ); 00362 00363 //it's ok if these are empty strings, I take care of it later... 00364 args.append( name ); 00365 args.append( clazzName ); 00366 args.append( baseURL ); 00367 args.append( user ); 00368 args.append( password ); 00369 args.append( authname ); 00370 args.append( codeBase ); 00371 args.append( jarFile ); 00372 00373 args.append( QString::number( size.width() ) ); 00374 args.append( QString::number( size.height() ) ); 00375 00376 args.append( windowTitle ); 00377 00378 //add on the number of parameter pairs... 00379 const int num = params.count(); 00380 const QString num_params = QString("%1").arg( num, 8 ); 00381 args.append( num_params ); 00382 00383 QMap< QString, QString >::ConstIterator it = params.begin(); 00384 const QMap< QString, QString >::ConstIterator itEnd = params.end(); 00385 00386 for( ; it != itEnd; ++it ) 00387 { 00388 args.append( it.key() ); 00389 args.append( it.value() ); 00390 } 00391 00392 process->send( KJAS_CREATE_APPLET, args ); 00393 00394 return true; 00395 } 00396 00397 void KJavaAppletServer::initApplet( int contextId, int appletId ) 00398 { 00399 if ( d->javaProcessFailed ) return; 00400 QStringList args; 00401 args.append( QString::number( contextId ) ); 00402 args.append( QString::number( appletId ) ); 00403 00404 process->send( KJAS_INIT_APPLET, args ); 00405 } 00406 00407 void KJavaAppletServer::destroyApplet( int contextId, int appletId ) 00408 { 00409 if ( d->javaProcessFailed ) return; 00410 QStringList args; 00411 args.append( QString::number(contextId) ); 00412 args.append( QString::number(appletId) ); 00413 00414 process->send( KJAS_DESTROY_APPLET, args ); 00415 } 00416 00417 void KJavaAppletServer::startApplet( int contextId, int appletId ) 00418 { 00419 if ( d->javaProcessFailed ) return; 00420 QStringList args; 00421 args.append( QString::number(contextId) ); 00422 args.append( QString::number(appletId) ); 00423 00424 process->send( KJAS_START_APPLET, args ); 00425 } 00426 00427 void KJavaAppletServer::stopApplet( int contextId, int appletId ) 00428 { 00429 if ( d->javaProcessFailed ) return; 00430 QStringList args; 00431 args.append( QString::number(contextId) ); 00432 args.append( QString::number(appletId) ); 00433 00434 process->send( KJAS_STOP_APPLET, args ); 00435 } 00436 00437 void KJavaAppletServer::showConsole() { 00438 if ( d->javaProcessFailed ) return; 00439 QStringList args; 00440 process->send( KJAS_SHOW_CONSOLE, args ); 00441 } 00442 00443 void KJavaAppletServer::sendURLData( int loaderID, int code, const QByteArray& data ) 00444 { 00445 QStringList args; 00446 args.append( QString::number(loaderID) ); 00447 args.append( QString::number(code) ); 00448 00449 process->send( KJAS_URLDATA, args, data ); 00450 } 00451 00452 void KJavaAppletServer::removeDataJob( int loaderID ) 00453 { 00454 const KIOJobMap::iterator it = d->kiojobs.find( loaderID ); 00455 if (it != d->kiojobs.end()) { 00456 it.value()->deleteLater(); 00457 d->kiojobs.erase( it ); 00458 } 00459 } 00460 00461 void KJavaAppletServer::quit() 00462 { 00463 const QStringList args; 00464 00465 process->send( KJAS_SHUTDOWN_SERVER, args ); 00466 process->waitForFinished( 10000 ); 00467 } 00468 00469 void KJavaAppletServer::slotJavaRequest( const QByteArray& qb ) 00470 { 00471 // qb should be one command only without the length string, 00472 // we parse out the command and it's meaning here... 00473 QString cmd; 00474 QStringList args; 00475 int index = 0; 00476 const int qb_size = qb.size(); 00477 00478 //get the command code 00479 const char cmd_code = qb[ index++ ]; 00480 ++index; //skip the next sep 00481 00482 //get contextID 00483 QString contextID; 00484 while( index < qb_size && qb[index] != 0 ) 00485 { 00486 contextID += qb[ index++ ]; 00487 } 00488 bool ok; 00489 const int ID_num = contextID.toInt( &ok ); // context id or kio job id 00490 /*if (d->locked_context > -1 && 00491 ID_num != d->locked_context && 00492 (cmd_code == KJAS_JAVASCRIPT_EVENT || 00493 cmd_code == KJAS_APPLET_STATE || 00494 cmd_code == KJAS_APPLET_FAILED)) 00495 { 00496 / * Don't allow requests from other contexts if we're waiting 00497 * on a return value that can trigger JavaScript events 00498 * / 00499 d->java_requests.push_back(qb); 00500 return; 00501 }*/ 00502 ++index; //skip the sep 00503 00504 if (cmd_code == KJAS_PUT_DATA) { 00505 // rest of the data is for kio put 00506 if (ok) { 00507 KIOJobMap::iterator it = d->kiojobs.find( ID_num ); 00508 if (ok && it != d->kiojobs.end()) { 00509 QByteArray qba; 00510 qba = QByteArray::fromRawData(qb.data() + index, qb.size() - index - 1); 00511 it.value()->data(qba); 00512 qba = QByteArray::fromRawData(qb.data() + index, qb.size() - index - 1); 00513 } 00514 kDebug(6100) << "PutData(" << ID_num << ") size=" << qb.size() - index; 00515 } else 00516 kError(6100) << "PutData error " << ok << endl; 00517 return; 00518 } 00519 //now parse out the arguments 00520 while( index < qb_size ) 00521 { 00522 int sep_pos = qb.indexOf( (char) 0, index ); 00523 if (sep_pos < 0) { 00524 kError(6100) << "Missing separation byte" << endl; 00525 sep_pos = qb_size; 00526 } 00527 //kDebug(6100) << "KJavaAppletServer::slotJavaRequest: "<< QString::fromLocal8Bit( qb.data() + index, sep_pos - index ); 00528 args.append( QString::fromLocal8Bit( qb.data() + index, sep_pos - index ) ); 00529 index = sep_pos + 1; //skip the sep 00530 } 00531 //here I should find the context and call the method directly 00532 //instead of emitting signals 00533 switch( cmd_code ) 00534 { 00535 case KJAS_SHOW_DOCUMENT: 00536 cmd = QLatin1String( "showdocument" ); 00537 break; 00538 00539 case KJAS_SHOW_URLINFRAME: 00540 cmd = QLatin1String( "showurlinframe" ); 00541 break; 00542 00543 case KJAS_SHOW_STATUS: 00544 cmd = QLatin1String( "showstatus" ); 00545 break; 00546 00547 case KJAS_RESIZE_APPLET: 00548 cmd = QLatin1String( "resizeapplet" ); 00549 break; 00550 00551 case KJAS_GET_URLDATA: 00552 if (ok && !args.empty() ) { 00553 d->kiojobs.insert(ID_num, new KJavaDownloader(ID_num, args.first())); 00554 kDebug(6100) << "GetURLData(" << ID_num << ") url=" << args.first(); 00555 } else 00556 kError(6100) << "GetURLData error " << ok << " args:" << args.size() << endl; 00557 return; 00558 case KJAS_PUT_URLDATA: 00559 if (ok && !args.empty()) { 00560 KJavaUploader* const job = new KJavaUploader(ID_num, args.first()); 00561 d->kiojobs.insert(ID_num, job); 00562 job->start(); 00563 kDebug(6100) << "PutURLData(" << ID_num << ") url=" << args.first(); 00564 } else 00565 kError(6100) << "PutURLData error " << ok << " args:" << args.size() << endl; 00566 return; 00567 case KJAS_DATA_COMMAND: 00568 if (ok && !args.empty()) { 00569 const int cmd = args.first().toInt( &ok ); 00570 KIOJobMap::iterator it = d->kiojobs.find( ID_num ); 00571 if (ok && it != d->kiojobs.end()) 00572 it.value()->jobCommand( cmd ); 00573 kDebug(6100) << "KIO Data command: " << ID_num << " " << args.first(); 00574 } else 00575 kError(6100) << "KIO Data command error " << ok << " args:" << args.size() << endl; 00576 return; 00577 case KJAS_JAVASCRIPT_EVENT: 00578 cmd = QLatin1String( "JS_Event" ); 00579 00580 if(!args.empty()) { 00581 kDebug(6100) << "Javascript request: "<< contextID 00582 << " code: " << args[0] << endl; 00583 } else { 00584 kError(6100) << "Expected args not to be empty!" << endl; 00585 } 00586 00587 break; 00588 case KJAS_GET_MEMBER: 00589 case KJAS_PUT_MEMBER: 00590 case KJAS_CALL_MEMBER: { 00591 if(!args.empty()) { 00592 const int ticket = args[0].toInt(); 00593 JSStack::iterator it = d->jsstack.find(ticket); 00594 if (it != d->jsstack.end()) { 00595 kDebug(6100) << "slotJavaRequest: " << ticket; 00596 args.pop_front(); 00597 it.value()->args.operator=(args); // just in case .. 00598 it.value()->ready = true; 00599 it.value()->exit = true; 00600 } else 00601 kDebug(6100) << "Error: Missed return member data"; 00602 } else { 00603 kError(6100) << "Expected args not to be empty!" << endl; 00604 } 00605 return; 00606 } 00607 case KJAS_AUDIOCLIP_PLAY: 00608 cmd = QLatin1String( "audioclip_play" ); 00609 if(!args.empty()) 00610 kDebug(6100) << "Audio Play: url=" << args[0]; 00611 else 00612 kError(6100) << "Expected args not to be empty!" << endl; 00613 00614 break; 00615 case KJAS_AUDIOCLIP_LOOP: 00616 cmd = QLatin1String( "audioclip_loop" ); 00617 if(!args.empty()) 00618 kDebug(6100) << "Audio Loop: url=" << args[0]; 00619 else 00620 kError(6100) << "Expected args not to be empty!" << endl; 00621 00622 break; 00623 case KJAS_AUDIOCLIP_STOP: 00624 cmd = QLatin1String( "audioclip_stop" ); 00625 if(!args.empty()) 00626 kDebug(6100) << "Audio Stop: url=" << args[0]; 00627 else 00628 kError(6100) << "Expected args not to be empty!" << endl; 00629 00630 break; 00631 case KJAS_APPLET_STATE: 00632 if(args.size() > 1) 00633 kDebug(6100) << "Applet State Notification for Applet " << args[0] << ". New state=" << args[1]; 00634 else 00635 kError(6100) << "Expected args not to be empty!" << endl; 00636 00637 cmd = QLatin1String( "AppletStateNotification" ); 00638 break; 00639 case KJAS_APPLET_FAILED: 00640 if(args.size() > 1) 00641 kDebug(6100) << "Applet " << args[0] << " Failed: " << args[1]; 00642 else 00643 kError(6100) << "Expected args not to be empty!" << endl; 00644 00645 cmd = QLatin1String( "AppletFailed" ); 00646 break; 00647 case KJAS_SECURITY_CONFIRM: { 00648 if (KSSL::doesSSLWork() && !d->kssl) 00649 d->kssl = new KSSL; 00650 QStringList sl; 00651 QString answer( "invalid" ); 00652 00653 if (!d->kssl) { 00654 answer = "nossl"; 00655 } else if (args.size() > 2) { 00656 const int certsnr = args[1].toInt(); 00657 Q_ASSERT(args.size() > certsnr + 1); 00658 QString text; 00659 QList<KSSLCertificate *> certs; 00660 for (int i = certsnr - 1; i >= 0; --i) { 00661 const QByteArray &arg = args[i + 2].toAscii(); 00662 KSSLCertificate * cert = KSSLCertificate::fromString(arg.constData()); 00663 if (cert) { 00664 certs.prepend(cert); 00665 if (cert->isSigner()) 00666 text += i18n("Signed by (validation: %1)", KSSLCertificate::verifyText(cert->validate())); 00667 else 00668 text += i18n("Certificate (validation: %1)", KSSLCertificate::verifyText(cert->validate())); 00669 text += "\n"; 00670 QString subject = cert->getSubject() + QChar('\n'); 00671 QRegExp reg(QString("/[A-Z]+=")); 00672 int pos = 0; 00673 while ((pos = subject.indexOf(reg, pos)) > -1) 00674 subject.replace(pos, 1, QString("\n ")); 00675 text += subject.mid(1); 00676 } 00677 } 00678 kDebug(6100) << "Security confirm " << args.first() << certs.count(); 00679 if ( !certs.isEmpty() ) { 00680 KSSLCertChain chain; 00681 chain.setChain( certs ); 00682 if ( chain.isValid() ) 00683 answer = PermissionDialog( qApp->activeWindow() ).exec( text, args[0] ); 00684 } 00685 qDeleteAll(certs); 00686 } 00687 sl.push_front( answer ); 00688 sl.push_front( QString::number(ID_num) ); 00689 process->send( KJAS_SECURITY_CONFIRM, sl ); 00690 return; 00691 } 00692 default: 00693 return; 00694 break; 00695 } 00696 00697 00698 if( !ok ) 00699 { 00700 kError(6100) << "could not parse out contextID to call command on" << endl; 00701 return; 00702 } 00703 00704 KJavaAppletContext* const context = d->contexts[ ID_num ]; 00705 if( context ) 00706 context->processCmd( cmd, args ); 00707 else if (cmd != "AppletStateNotification") 00708 kError(6100) << "no context object for this id" << endl; 00709 } 00710 00711 void KJavaAppletServer::killTimers() 00712 { 00713 QAbstractEventDispatcher::instance()->unregisterTimers(this); 00714 } 00715 00716 void KJavaAppletServer::endWaitForReturnData() { 00717 kDebug(6100) << "KJavaAppletServer::endWaitForReturnData"; 00718 killTimers(); 00719 JSStack::iterator it = d->jsstack.begin(); 00720 JSStack::iterator itEnd = d->jsstack.end(); 00721 for (; it != itEnd; ++it) 00722 it.value()->exit = true; 00723 } 00724 00725 void KJavaAppletServer::timerEvent(QTimerEvent *) { 00726 endWaitForReturnData(); 00727 kDebug(6100) << "KJavaAppletServer::timerEvent timeout"; 00728 } 00729 00730 void KJavaAppletServer::waitForReturnData(JSStackFrame * frame) { 00731 kDebug(6100) << ">KJavaAppletServer::waitForReturnData"; 00732 killTimers(); 00733 startTimer(15000); 00734 while (!frame->exit) { 00735 QAbstractEventDispatcher::instance()->processEvents (QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents); 00736 } 00737 if (d->jsstack.size() <= 1) 00738 killTimers(); 00739 kDebug(6100) << "<KJavaAppletServer::waitForReturnData stacksize:" << d->jsstack.size(); 00740 } 00741 00742 bool KJavaAppletServer::getMember(QStringList & args, QStringList & ret_args) { 00743 JSStackFrame frame( d->jsstack, ret_args ); 00744 args.push_front( QString::number(frame.ticket) ); 00745 00746 process->send( KJAS_GET_MEMBER, args ); 00747 waitForReturnData( &frame ); 00748 00749 return frame.ready; 00750 } 00751 00752 bool KJavaAppletServer::putMember( QStringList & args ) { 00753 QStringList ret_args; 00754 JSStackFrame frame( d->jsstack, ret_args ); 00755 args.push_front( QString::number(frame.ticket) ); 00756 00757 process->send( KJAS_PUT_MEMBER, args ); 00758 waitForReturnData( &frame ); 00759 00760 return frame.ready && ret_args.count() > 0 && ret_args[0].toInt(); 00761 } 00762 00763 bool KJavaAppletServer::callMember(QStringList & args, QStringList & ret_args) { 00764 JSStackFrame frame( d->jsstack, ret_args ); 00765 args.push_front( QString::number(frame.ticket) ); 00766 00767 process->send( KJAS_CALL_MEMBER, args ); 00768 waitForReturnData( &frame ); 00769 00770 return frame.ready; 00771 } 00772 00773 void KJavaAppletServer::derefObject( QStringList & args ) { 00774 process->send( KJAS_DEREF_OBJECT, args ); 00775 } 00776 00777 bool KJavaAppletServer::usingKIO() { 00778 return d->useKIO; 00779 } 00780 00781 00782 PermissionDialog::PermissionDialog( QWidget* parent ) 00783 : QObject(parent), m_button("no") 00784 {} 00785 00786 QString PermissionDialog::exec( const QString & cert, const QString & perm ) { 00787 QPointer<QDialog> dialog = new QDialog( static_cast<QWidget*>(parent()) ); 00788 00789 dialog->setObjectName("PermissionDialog"); 00790 QSizePolicy sizeplcy( QSizePolicy::Minimum, QSizePolicy::Minimum); 00791 sizeplcy.setHeightForWidth(dialog->sizePolicy().hasHeightForWidth()); 00792 dialog->setSizePolicy(sizeplcy); 00793 dialog->setModal( true ); 00794 dialog->setWindowTitle( i18n("Security Alert") ); 00795 00796 QVBoxLayout* const dialogLayout = new QVBoxLayout( dialog ); 00797 dialogLayout->setObjectName("dialogLayout"); 00798 00799 dialogLayout->addWidget( new QLabel( i18n("Do you grant Java applet with certificate(s):"), dialog ) ); 00800 dialogLayout->addWidget( new QLabel( cert, dialog ) ); 00801 dialogLayout->addWidget( new QLabel( i18n("the following permission"), dialog ) ); 00802 dialogLayout->addWidget( new QLabel( perm, dialog ) ); 00803 QSpacerItem* const spacer2 = new QSpacerItem( 20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding ); 00804 dialogLayout->addItem( spacer2 ); 00805 00806 QHBoxLayout* const buttonLayout = new QHBoxLayout(); 00807 buttonLayout->setMargin(0); 00808 buttonLayout->setObjectName("buttonLayout"); 00809 00810 QPushButton* const no = new QPushButton( i18n("&No"), dialog ); 00811 no->setDefault( true ); 00812 buttonLayout->addWidget( no ); 00813 00814 QPushButton* const reject = new QPushButton( i18n("&Reject All"), dialog ); 00815 buttonLayout->addWidget( reject ); 00816 00817 QPushButton* const yes = new QPushButton( i18n("&Yes"), dialog ); 00818 buttonLayout->addWidget( yes ); 00819 00820 QPushButton* const grant = new QPushButton( i18n("&Grant All"), dialog ); 00821 buttonLayout->addWidget( grant ); 00822 dialogLayout->addLayout( buttonLayout ); 00823 dialog->resize( dialog->minimumSizeHint() ); 00824 //clearWState( WState_Polished ); 00825 00826 connect( no, SIGNAL(clicked()), this, SLOT(clicked()) ); 00827 connect( reject, SIGNAL(clicked()), this, SLOT(clicked()) ); 00828 connect( yes, SIGNAL(clicked()), this, SLOT(clicked()) ); 00829 connect( grant, SIGNAL(clicked()), this, SLOT(clicked()) ); 00830 00831 dialog->exec(); 00832 delete dialog; 00833 00834 return m_button; 00835 } 00836 00837 PermissionDialog::~PermissionDialog() 00838 {} 00839 00840 void PermissionDialog::clicked() 00841 { 00842 m_button = sender()->objectName(); 00843 static_cast<const QWidget*>(sender())->parentWidget()->close(); 00844 } 00845 00846 #include "kjavaappletserver.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 18:53:08 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 18:53:08 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.