khtml Library API Documentation

kjavaappletserver.cpp

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