KHtml

kjavaappletserver.cpp
1 /* This file is part of the KDE project
2  *
3  * Copyright (C) 2000 Richard Moore <[email protected]>
4  * 2000 Wynn Wilkes <[email protected]>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 #include "kjavaappletserver.h"
23 
24 #include "kjavaappletcontext.h"
25 #include "kjavadownloader.h"
26 
27 #include "kjavaappletviewer_debug.h"
28 #include <kconfig.h>
29 #include <kconfiggroup.h>
30 #include <klocalizedstring.h>
31 #include <kparts/browserextension.h>
32 
33 #include <kio/job.h>
34 #include <kprotocolmanager.h>
35 #include <qsslcertificate.h>
36 
37 #include <QTimer>
38 #include <QPointer>
39 #include <QDir>
40 #include <QEventLoop>
41 #include <QSslSocket>
42 #include <QApplication>
43 #include <QLabel>
44 #include <QDialog>
45 #include <QPushButton>
46 #include <QLayout>
47 #include <QRegExp>
48 
49 #include <stdlib.h>
50 #include <assert.h>
51 #include <QAbstractEventDispatcher>
52 #include <qstandardpaths.h>
53 
54 #define KJAS_CREATE_CONTEXT (char)1
55 #define KJAS_DESTROY_CONTEXT (char)2
56 #define KJAS_CREATE_APPLET (char)3
57 #define KJAS_DESTROY_APPLET (char)4
58 #define KJAS_START_APPLET (char)5
59 #define KJAS_STOP_APPLET (char)6
60 #define KJAS_INIT_APPLET (char)7
61 #define KJAS_SHOW_DOCUMENT (char)8
62 #define KJAS_SHOW_URLINFRAME (char)9
63 #define KJAS_SHOW_STATUS (char)10
64 #define KJAS_RESIZE_APPLET (char)11
65 #define KJAS_GET_URLDATA (char)12
66 #define KJAS_URLDATA (char)13
67 #define KJAS_SHUTDOWN_SERVER (char)14
68 #define KJAS_JAVASCRIPT_EVENT (char)15
69 #define KJAS_GET_MEMBER (char)16
70 #define KJAS_CALL_MEMBER (char)17
71 #define KJAS_PUT_MEMBER (char)18
72 #define KJAS_DEREF_OBJECT (char)19
73 #define KJAS_AUDIOCLIP_PLAY (char)20
74 #define KJAS_AUDIOCLIP_LOOP (char)21
75 #define KJAS_AUDIOCLIP_STOP (char)22
76 #define KJAS_APPLET_STATE (char)23
77 #define KJAS_APPLET_FAILED (char)24
78 #define KJAS_DATA_COMMAND (char)25
79 #define KJAS_PUT_URLDATA (char)26
80 #define KJAS_PUT_DATA (char)27
81 #define KJAS_SECURITY_CONFIRM (char)28
82 #define KJAS_SHOW_CONSOLE (char)29
83 
84 class JSStackFrame;
85 
88 
89 class JSStackFrame
90 {
91 public:
92  JSStackFrame(JSStack &stack, QStringList &a)
93  : jsstack(stack), args(a), ticket(counter++), ready(false), exit(false)
94  {
95  jsstack.insert(ticket, this);
96  }
97  ~JSStackFrame()
98  {
99  jsstack.remove(ticket);
100  }
101  JSStack &jsstack;
102  QStringList &args;
103  int ticket;
104  bool ready : 1;
105  bool exit : 1;
106  static int counter;
107 };
108 
109 int JSStackFrame::counter = 0;
110 
111 class KJavaAppletServerPrivate
112 {
113  friend class KJavaAppletServer;
114 private:
115  KJavaAppletServerPrivate() {}
116  ~KJavaAppletServerPrivate()
117  {
118  }
119  int counter;
121  QString appletLabel;
122  JSStack jsstack;
123  KIOJobMap kiojobs;
124  bool javaProcessFailed;
125  bool useKIO;
126  //int locked_context;
127  //QValueList<QByteArray> java_requests;
128 };
129 
130 static KJavaAppletServer *self = nullptr;
131 
132 KJavaAppletServer::KJavaAppletServer()
133  : d(new KJavaAppletServerPrivate)
134 {
135  process = new KJavaProcess();
136 
137  connect(process, SIGNAL(received(QByteArray)),
138  this, SLOT(slotJavaRequest(QByteArray)));
139 
140  setupJava(process);
141 
142  if (process->startJava()) {
143  d->appletLabel = i18n("Loading Applet");
144  d->javaProcessFailed = false;
145  } else {
146  d->appletLabel = i18n("Error: java executable not found");
147  d->javaProcessFailed = true;
148  }
149 }
150 
151 KJavaAppletServer::~KJavaAppletServer()
152 {
153  disconnect(process, nullptr, nullptr, nullptr); // first disconnect from process.
154  quit();
155 
156  delete process;
157  process = nullptr;
158  delete d;
159 }
160 
161 QString KJavaAppletServer::getAppletLabel()
162 {
163  if (self) {
164  return self->appletLabel();
165  } else {
166  return QString();
167  }
168 }
169 
170 QString KJavaAppletServer::appletLabel()
171 {
172  return d->appletLabel;
173 }
174 
175 KJavaAppletServer *KJavaAppletServer::allocateJavaServer()
176 {
177  if (self == nullptr) {
178  self = new KJavaAppletServer();
179  self->d->counter = 0;
180  }
181 
182  ++(self->d->counter);
183  return self;
184 }
185 
186 void KJavaAppletServer::freeJavaServer()
187 {
188  --(self->d->counter);
189 
190  if (self->d->counter == 0) {
191  //instead of immediately quitting here, set a timer to kill us
192  //if there are still no servers- give us one minute
193  //this is to prevent repeated loading and unloading of the jvm
194  KConfig config("konquerorrc");
195  KConfigGroup group = config.group("Java/JavaScript Settings");
196  if (group.readEntry("ShutdownAppletServer", true)) {
197  const int value = group.readEntry("AppletServerTimeout", 60);
198  QTimer::singleShot(value * 1000, self, SLOT(checkShutdown()));
199  }
200  }
201 }
202 
203 void KJavaAppletServer::checkShutdown()
204 {
205  if (self->d->counter == 0) {
206  delete self;
207  self = nullptr;
208  }
209 }
210 
211 void KJavaAppletServer::setupJava(KJavaProcess *p)
212 {
213  KConfig configFile("konquerorrc");
214  KConfigGroup config(&configFile, "Java/JavaScript Settings");
215 
216  QString jvm_path = "java";
217 
218  QString jPath = config.readPathEntry("JavaPath", QString());
219  if (!jPath.isEmpty() && jPath != "java") {
220  // Cut off trailing slash if any
221  if (jPath[jPath.length() - 1] == '/') {
222  jPath.remove(jPath.length() - 1, 1);
223  }
224 
225  QDir dir(jPath);
226  if (dir.exists("bin/java")) {
227  jvm_path = jPath + "/bin/java";
228  } else if (dir.exists("/jre/bin/java")) {
229  jvm_path = jPath + "/jre/bin/java";
230  } else if (QFile::exists(jPath)) {
231  //check here to see if they entered the whole path the java exe
232  jvm_path = jPath;
233  }
234  }
235 
236  //check to see if jvm_path is valid and set d->appletLabel accordingly
237  p->setJVMPath(jvm_path);
238 
239  // Prepare classpath variable
240  QString kjava_class = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kf5/kjava/kjava.jar");
241  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "kjava_class = " << kjava_class;
242  if (kjava_class.isNull()) { // Should not happen
243  return;
244  }
245 
246  QDir dir(kjava_class);
247  dir.cdUp();
248  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "dir = " << dir.absolutePath();
249 
250  const QStringList entries = dir.entryList(QDir::nameFiltersFromString("*.jar"));
251  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "entries = " << entries.join( ":" );
252 
253  QString classes;
254  {
255  QStringList::ConstIterator it = entries.begin();
256  const QStringList::ConstIterator itEnd = entries.end();
257  for (; it != itEnd; ++it) {
258  if (!classes.isEmpty()) {
259  classes += ':';
260  }
261  classes += dir.absoluteFilePath(*it);
262  }
263  }
264  p->setClasspath(classes);
265 
266  // Fix all the extra arguments
267  const QString extraArgs = config.readEntry("JavaArgs");
268  p->setExtraArgs(extraArgs);
269 
270  if (config.readEntry("UseSecurityManager", true)) {
271  QString class_file = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kjava/kjava.policy");
272  p->setSystemProperty("java.security.policy", class_file);
273 
274  p->setSystemProperty("java.security.manager",
275  "org.kde.kjas.server.KJASSecurityManager");
276  }
277 
278  d->useKIO = config.readEntry("UseKio", false);
279  if (d->useKIO) {
280  p->setSystemProperty("kjas.useKio", QString());
281  }
282 
283  //check for http proxies...
285  // only proxyForUrl honors automatic proxy scripts
286  // we do not know the applet url here so we just use a dummy url
287  // this is a workaround for now
288  // FIXME
289  const QUrl dummyURL("http://www.kde.org/");
290  const QString httpProxy = KProtocolManager::proxyForUrl(dummyURL);
291  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "httpProxy is " << httpProxy;
292 
293  const QUrl url(httpProxy);
294  p->setSystemProperty("http.proxyHost", url.host());
295  p->setSystemProperty("http.proxyPort", QString::number(url.port()));
296  }
297 
298  //set the main class to run
299  p->setMainClass("org.kde.kjas.server.Main");
300 }
301 
302 void KJavaAppletServer::createContext(int contextId, KJavaAppletContext *context)
303 {
304 // qCDebug(KJAVAAPPLETVIEWER_LOG) << "createContext: " << contextId;
305  if (d->javaProcessFailed) {
306  return;
307  }
308 
309  d->contexts.insert(contextId, context);
310 
311  QStringList args;
312  args.append(QString::number(contextId));
313  process->send(KJAS_CREATE_CONTEXT, args);
314 }
315 
316 void KJavaAppletServer::destroyContext(int contextId)
317 {
318 // qCDebug(KJAVAAPPLETVIEWER_LOG) << "destroyContext: " << contextId;
319  if (d->javaProcessFailed) {
320  return;
321  }
322  d->contexts.remove(contextId);
323 
324  QStringList args;
325  args.append(QString::number(contextId));
326  process->send(KJAS_DESTROY_CONTEXT, args);
327 }
328 
329 bool KJavaAppletServer::createApplet(int contextId, int appletId,
330  const QString &name, const QString &clazzName,
331  const QString &baseURL, const QString &user,
332  const QString &password, const QString &authname,
333  const QString &codeBase, const QString &jarFile,
334  QSize size, const QMap<QString, QString> &params,
335  const QString &windowTitle)
336 {
337 // qCDebug(KJAVAAPPLETVIEWER_LOG) << "createApplet: contextId = " << contextId << endl
338 // << " appletId = " << appletId << endl
339 // << " name = " << name << endl
340 // << " clazzName = " << clazzName << endl
341 // << " baseURL = " << baseURL << endl
342 // << " codeBase = " << codeBase << endl
343 // << " jarFile = " << jarFile << endl
344 // << " width = " << size.width() << endl
345 // << " height = " << size.height() << endl;
346 
347  if (d->javaProcessFailed) {
348  return false;
349  }
350 
351  QStringList args;
352  args.append(QString::number(contextId));
353  args.append(QString::number(appletId));
354 
355  //it's ok if these are empty strings, I take care of it later...
356  args.append(name);
357  args.append(clazzName);
358  args.append(baseURL);
359  args.append(user);
360  args.append(password);
361  args.append(authname);
362  args.append(codeBase);
363  args.append(jarFile);
364 
365  args.append(QString::number(size.width()));
366  args.append(QString::number(size.height()));
367 
368  args.append(windowTitle);
369 
370  //add on the number of parameter pairs...
371  const int num = params.count();
372  const QString num_params = QString("%1").arg(num, 8);
373  args.append(num_params);
374 
376  const QMap< QString, QString >::ConstIterator itEnd = params.end();
377 
378  for (; it != itEnd; ++it) {
379  args.append(it.key());
380  args.append(it.value());
381  }
382 
383  process->send(KJAS_CREATE_APPLET, args);
384 
385  return true;
386 }
387 
388 void KJavaAppletServer::initApplet(int contextId, int appletId)
389 {
390  if (d->javaProcessFailed) {
391  return;
392  }
393  QStringList args;
394  args.append(QString::number(contextId));
395  args.append(QString::number(appletId));
396 
397  process->send(KJAS_INIT_APPLET, args);
398 }
399 
400 void KJavaAppletServer::destroyApplet(int contextId, int appletId)
401 {
402  if (d->javaProcessFailed) {
403  return;
404  }
405  QStringList args;
406  args.append(QString::number(contextId));
407  args.append(QString::number(appletId));
408 
409  process->send(KJAS_DESTROY_APPLET, args);
410 }
411 
412 void KJavaAppletServer::startApplet(int contextId, int appletId)
413 {
414  if (d->javaProcessFailed) {
415  return;
416  }
417  QStringList args;
418  args.append(QString::number(contextId));
419  args.append(QString::number(appletId));
420 
421  process->send(KJAS_START_APPLET, args);
422 }
423 
424 void KJavaAppletServer::stopApplet(int contextId, int appletId)
425 {
426  if (d->javaProcessFailed) {
427  return;
428  }
429  QStringList args;
430  args.append(QString::number(contextId));
431  args.append(QString::number(appletId));
432 
433  process->send(KJAS_STOP_APPLET, args);
434 }
435 
436 void KJavaAppletServer::showConsole()
437 {
438  if (d->javaProcessFailed) {
439  return;
440  }
441  QStringList args;
442  process->send(KJAS_SHOW_CONSOLE, args);
443 }
444 
445 void KJavaAppletServer::sendURLData(int loaderID, int code, const QByteArray &data)
446 {
447  QStringList args;
448  args.append(QString::number(loaderID));
449  args.append(QString::number(code));
450 
451  process->send(KJAS_URLDATA, args, data);
452 }
453 
454 void KJavaAppletServer::removeDataJob(int loaderID)
455 {
456  const KIOJobMap::iterator it = d->kiojobs.find(loaderID);
457  if (it != d->kiojobs.end()) {
458  it.value()->deleteLater();
459  d->kiojobs.erase(it);
460  }
461 }
462 
463 void KJavaAppletServer::quit()
464 {
465  const QStringList args;
466 
467  process->send(KJAS_SHUTDOWN_SERVER, args);
468  process->waitForFinished(10000);
469 }
470 
471 void KJavaAppletServer::slotJavaRequest(const QByteArray &qb)
472 {
473  // qb should be one command only without the length string,
474  // we parse out the command and it's meaning here...
475  QString cmd;
476  QStringList args;
477  int index = 0;
478  const int qb_size = qb.size();
479 
480  //get the command code
481  const char cmd_code = qb[ index++ ];
482  ++index; //skip the next sep
483 
484  //get contextID
485  QString contextID;
486  while (index < qb_size && qb[index] != 0) {
487  contextID += qb[ index++ ];
488  }
489  bool ok;
490  const int ID_num = contextID.toInt(&ok); // context id or kio job id
491  /*if (d->locked_context > -1 &&
492  ID_num != d->locked_context &&
493  (cmd_code == KJAS_JAVASCRIPT_EVENT ||
494  cmd_code == KJAS_APPLET_STATE ||
495  cmd_code == KJAS_APPLET_FAILED))
496  {
497  / * Don't allow requests from other contexts if we're waiting
498  * on a return value that can trigger JavaScript events
499  * /
500  d->java_requests.push_back(qb);
501  return;
502  }*/
503  ++index; //skip the sep
504 
505  if (cmd_code == KJAS_PUT_DATA) {
506  // rest of the data is for kio put
507  if (ok) {
508  KIOJobMap::iterator it = d->kiojobs.find(ID_num);
509  if (ok && it != d->kiojobs.end()) {
510  QByteArray qba;
511  qba = QByteArray::fromRawData(qb.data() + index, qb.size() - index - 1);
512  it.value()->data(qba);
513  qba = QByteArray::fromRawData(qb.data() + index, qb.size() - index - 1);
514  }
515  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "PutData(" << ID_num << ") size=" << qb.size() - index;
516  } else {
517  qCCritical(KJAVAAPPLETVIEWER_LOG) << "PutData error " << ok;
518  }
519  return;
520  }
521  //now parse out the arguments
522  while (index < qb_size) {
523  int sep_pos = qb.indexOf((char) 0, index);
524  if (sep_pos < 0) {
525  qCCritical(KJAVAAPPLETVIEWER_LOG) << "Missing separation byte";
526  sep_pos = qb_size;
527  }
528  //qCDebug(KJAVAAPPLETVIEWER_LOG) << "KJavaAppletServer::slotJavaRequest: "<< QString::fromLocal8Bit( qb.data() + index, sep_pos - index );
529  args.append(QString::fromLocal8Bit(qb.data() + index, sep_pos - index));
530  index = sep_pos + 1; //skip the sep
531  }
532  //here I should find the context and call the method directly
533  //instead of emitting signals
534  switch (cmd_code) {
535  case KJAS_SHOW_DOCUMENT:
536  cmd = QLatin1String("showdocument");
537  break;
538 
539  case KJAS_SHOW_URLINFRAME:
540  cmd = QLatin1String("showurlinframe");
541  break;
542 
543  case KJAS_SHOW_STATUS:
544  cmd = QLatin1String("showstatus");
545  break;
546 
547  case KJAS_RESIZE_APPLET:
548  cmd = QLatin1String("resizeapplet");
549  break;
550 
551  case KJAS_GET_URLDATA:
552  if (ok && !args.empty()) {
553  d->kiojobs.insert(ID_num, new KJavaDownloader(ID_num, args.first()));
554  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "GetURLData(" << ID_num << ") url=" << args.first();
555  } else {
556  qCCritical(KJAVAAPPLETVIEWER_LOG) << "GetURLData error " << ok << " args:" << args.size();
557  }
558  return;
559  case KJAS_PUT_URLDATA:
560  if (ok && !args.empty()) {
561  KJavaUploader *const job = new KJavaUploader(ID_num, args.first());
562  d->kiojobs.insert(ID_num, job);
563  job->start();
564  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "PutURLData(" << ID_num << ") url=" << args.first();
565  } else {
566  qCCritical(KJAVAAPPLETVIEWER_LOG) << "PutURLData error " << ok << " args:" << args.size();
567  }
568  return;
569  case KJAS_DATA_COMMAND:
570  if (ok && !args.empty()) {
571  const int cmd = args.first().toInt(&ok);
572  KIOJobMap::iterator it = d->kiojobs.find(ID_num);
573  if (ok && it != d->kiojobs.end()) {
574  it.value()->jobCommand(cmd);
575  }
576  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "KIO Data command: " << ID_num << " " << args.first();
577  } else {
578  qCCritical(KJAVAAPPLETVIEWER_LOG) << "KIO Data command error " << ok << " args:" << args.size();
579  }
580  return;
581  case KJAS_JAVASCRIPT_EVENT:
582  cmd = QLatin1String("JS_Event");
583 
584  if (!args.empty()) {
585  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "Javascript request: "<< contextID
586  // << " code: " << args[0] << endl;
587  } else {
588  qCCritical(KJAVAAPPLETVIEWER_LOG) << "Expected args not to be empty!";
589  }
590 
591  break;
592  case KJAS_GET_MEMBER:
593  case KJAS_PUT_MEMBER:
594  case KJAS_CALL_MEMBER: {
595  if (!args.empty()) {
596  const int ticket = args[0].toInt();
597  JSStack::iterator it = d->jsstack.find(ticket);
598  if (it != d->jsstack.end()) {
599  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "slotJavaRequest: " << ticket;
600  args.pop_front();
601  it.value()->args.operator = (args); // just in case ..
602  it.value()->ready = true;
603  it.value()->exit = true;
604  } else {
605  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "Error: Missed return member data";
606  }
607  } else {
608  qCCritical(KJAVAAPPLETVIEWER_LOG) << "Expected args not to be empty!";
609  }
610  return;
611  }
612  case KJAS_AUDIOCLIP_PLAY:
613  cmd = QLatin1String("audioclip_play");
614  if (!args.empty()) {
615  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "Audio Play: url=" << args[0];
616  } else {
617  qCCritical(KJAVAAPPLETVIEWER_LOG) << "Expected args not to be empty!";
618  }
619 
620  break;
621  case KJAS_AUDIOCLIP_LOOP:
622  cmd = QLatin1String("audioclip_loop");
623  if (!args.empty()) {
624  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "Audio Loop: url=" << args[0];
625  } else {
626  qCCritical(KJAVAAPPLETVIEWER_LOG) << "Expected args not to be empty!";
627  }
628 
629  break;
630  case KJAS_AUDIOCLIP_STOP:
631  cmd = QLatin1String("audioclip_stop");
632  if (!args.empty()) {
633  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "Audio Stop: url=" << args[0];
634  } else {
635  qCCritical(KJAVAAPPLETVIEWER_LOG) << "Expected args not to be empty!";
636  }
637 
638  break;
639  case KJAS_APPLET_STATE:
640  if (args.size() > 1) {
641  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "Applet State Notification for Applet " << args[0] << ". New state=" << args[1];
642  } else {
643  qCCritical(KJAVAAPPLETVIEWER_LOG) << "Expected args not to be empty!";
644  }
645 
646  cmd = QLatin1String("AppletStateNotification");
647  break;
648  case KJAS_APPLET_FAILED:
649  if (args.size() > 1) {
650  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "Applet " << args[0] << " Failed: " << args[1];
651  } else {
652  qCCritical(KJAVAAPPLETVIEWER_LOG) << "Expected args not to be empty!";
653  }
654 
655  cmd = QLatin1String("AppletFailed");
656  break;
657  case KJAS_SECURITY_CONFIRM: {
658  QStringList sl;
659  QString answer("invalid");
660 
661  if (!QSslSocket::supportsSsl()) {
662  answer = "nossl";
663  } else if (args.size() > 2) {
664  const int certsnr = args[1].toInt();
665  Q_ASSERT(args.size() > certsnr + 1);
666  QString text;
667  for (int i = certsnr - 1; i >= 0; --i) {
668  const QByteArray &arg = args[i + 2].toLatin1();
669  QSslCertificate cert(arg);
670  if (!cert.isNull()) {
671 #if 0 // KDE 5 TODO: finish port
672  if (cert.isSigner()) {
673  text += i18n("Signed by (validation: %1)", KSSLCertificate::verifyText(cert.validate()));
674  } else {
675  text += i18n("Certificate (validation: %1)", KSSLCertificate::verifyText(cert.validate()));
676  }
677  text += "\n";
678  QString subject = cert.getSubject() + QChar('\n');
679  QRegExp reg(QString("/[A-Z]+="));
680  int pos = 0;
681  while ((pos = subject.indexOf(reg, pos)) > -1) {
682  subject.replace(pos, 1, QString("\n "));
683  }
684  text += subject.mid(1);
685 #else
686  text += "TODO Security confirm";
687 #endif
688  }
689  }
690  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "Security confirm " << args.first() << certs.count();
691  if (!text.isEmpty()) {
692  answer = PermissionDialog(qApp->activeWindow()).exec(text, args[0]);
693  }
694  }
695  sl.push_front(answer);
696  sl.push_front(QString::number(ID_num));
697  process->send(KJAS_SECURITY_CONFIRM, sl);
698  return;
699  }
700  default:
701  return;
702  break;
703  }
704 
705  if (!ok) {
706  qCCritical(KJAVAAPPLETVIEWER_LOG) << "could not parse out contextID to call command on";
707  return;
708  }
709 
710  KJavaAppletContext *const context = d->contexts[ ID_num ];
711  if (context) {
712  context->processCmd(cmd, args);
713  } else if (cmd != "AppletStateNotification") {
714  qCCritical(KJAVAAPPLETVIEWER_LOG) << "no context object for this id";
715  }
716 }
717 
718 void KJavaAppletServer::killTimers()
719 {
721 }
722 
723 void KJavaAppletServer::endWaitForReturnData()
724 {
725  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "KJavaAppletServer::endWaitForReturnData";
726  killTimers();
727  JSStack::iterator it = d->jsstack.begin();
728  JSStack::iterator itEnd = d->jsstack.end();
729  for (; it != itEnd; ++it) {
730  it.value()->exit = true;
731  }
732 }
733 
734 void KJavaAppletServer::timerEvent(QTimerEvent *)
735 {
736  endWaitForReturnData();
737  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "KJavaAppletServer::timerEvent timeout";
738 }
739 
740 void KJavaAppletServer::waitForReturnData(JSStackFrame *frame)
741 {
742  // qCDebug(KJAVAAPPLETVIEWER_LOG) << ">KJavaAppletServer::waitForReturnData";
743  killTimers();
744  startTimer(15000);
745  while (!frame->exit) {
747  }
748  if (d->jsstack.size() <= 1) {
749  killTimers();
750  }
751  // qCDebug(KJAVAAPPLETVIEWER_LOG) << "<KJavaAppletServer::waitForReturnData stacksize:" << d->jsstack.size();
752 }
753 
754 bool KJavaAppletServer::getMember(QStringList &args, QStringList &ret_args)
755 {
756  JSStackFrame frame(d->jsstack, ret_args);
757  args.push_front(QString::number(frame.ticket));
758 
759  process->send(KJAS_GET_MEMBER, args);
760  waitForReturnData(&frame);
761 
762  return frame.ready;
763 }
764 
765 bool KJavaAppletServer::putMember(QStringList &args)
766 {
767  QStringList ret_args;
768  JSStackFrame frame(d->jsstack, ret_args);
769  args.push_front(QString::number(frame.ticket));
770 
771  process->send(KJAS_PUT_MEMBER, args);
772  waitForReturnData(&frame);
773 
774  return frame.ready && ret_args.count() > 0 && ret_args[0].toInt();
775 }
776 
777 bool KJavaAppletServer::callMember(QStringList &args, QStringList &ret_args)
778 {
779  JSStackFrame frame(d->jsstack, ret_args);
780  args.push_front(QString::number(frame.ticket));
781 
782  process->send(KJAS_CALL_MEMBER, args);
783  waitForReturnData(&frame);
784 
785  return frame.ready;
786 }
787 
788 void KJavaAppletServer::derefObject(QStringList &args)
789 {
790  process->send(KJAS_DEREF_OBJECT, args);
791 }
792 
793 bool KJavaAppletServer::usingKIO()
794 {
795  return d->useKIO;
796 }
797 
798 PermissionDialog::PermissionDialog(QWidget *parent)
799  : QObject(parent), m_button("no")
800 {}
801 
802 QString PermissionDialog::exec(const QString &cert, const QString &perm)
803 {
804  QPointer<QDialog> dialog = new QDialog(static_cast<QWidget *>(parent()));
805 
806  dialog->setObjectName("PermissionDialog");
808  sizeplcy.setHeightForWidth(dialog->sizePolicy().hasHeightForWidth());
809  dialog->setSizePolicy(sizeplcy);
810  dialog->setModal(true);
811  dialog->setWindowTitle(i18n("Security Alert"));
812 
813  QVBoxLayout *const dialogLayout = new QVBoxLayout(dialog);
814  dialogLayout->setObjectName("dialogLayout");
815 
816  dialogLayout->addWidget(new QLabel(i18n("Do you grant Java applet with certificate(s):"), dialog));
817  dialogLayout->addWidget(new QLabel(cert, dialog));
818  dialogLayout->addWidget(new QLabel(i18n("the following permission"), dialog));
819  dialogLayout->addWidget(new QLabel(perm, dialog));
821  dialogLayout->addItem(spacer2);
822 
823  QHBoxLayout *const buttonLayout = new QHBoxLayout();
824  buttonLayout->setContentsMargins(0, 0, 0, 0);
825  buttonLayout->setObjectName("buttonLayout");
826 
827  QPushButton *const no = new QPushButton(i18n("&No"), dialog);
828  no->setObjectName("no");
829  no->setDefault(true);
830  buttonLayout->addWidget(no);
831 
832  QPushButton *const reject = new QPushButton(i18n("&Reject All"), dialog);
833  reject->setObjectName("reject");
834  buttonLayout->addWidget(reject);
835 
836  QPushButton *const yes = new QPushButton(i18n("&Yes"), dialog);
837  yes->setObjectName("yes");
838  buttonLayout->addWidget(yes);
839 
840  QPushButton *const grant = new QPushButton(i18n("&Grant All"), dialog);
841  grant->setObjectName("grant");
842  buttonLayout->addWidget(grant);
843  dialogLayout->addLayout(buttonLayout);
844  dialog->resize(dialog->minimumSizeHint());
845  //clearWState( WState_Polished );
846 
847  connect(no, SIGNAL(clicked()), this, SLOT(clicked()));
848  connect(reject, SIGNAL(clicked()), this, SLOT(clicked()));
849  connect(yes, SIGNAL(clicked()), this, SLOT(clicked()));
850  connect(grant, SIGNAL(clicked()), this, SLOT(clicked()));
851 
852  dialog->exec();
853  delete dialog;
854 
855  return m_button;
856 }
857 
858 PermissionDialog::~PermissionDialog()
859 {}
860 
861 void PermissionDialog::clicked()
862 {
863  m_button = sender()->objectName();
864  static_cast<const QWidget *>(sender())->parentWidget()->close();
865 }
866 
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
bool close()
void setContentsMargins(int left, int top, int right, int bottom)
int width() const const
QAbstractEventDispatcher * instance(QThread *thread)
QObject * sender() const const
void push_front(const T &value)
QByteArray fromRawData(const char *data, int size)
bool exists() const const
QString & remove(int position, int n)
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
static bool useProxy()
bool supportsSsl()
int size() const const
KSharedConfigPtr config()
bool isNull() const const
QSize size() const const
static QString verifyText(KSSLValidation x)
int indexOf(char ch, int from) const const
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
QString number(int n, int base)
int count(const T &value) const const
QString fromLocal8Bit(const char *str, int size)
void append(const T &value)
bool empty() const const
void pop_front()
int toInt(bool *ok, int base) const const
virtual void addItem(QLayoutItem *item) override
void setObjectName(const QString &name)
bool isEmpty() const const
QPoint pos() const const
T & first()
QMap::iterator end()
QMap::iterator begin()
QList::iterator end()
const Key key(const T &value, const Key &defaultKey) const const
QString i18n(const char *text, const TYPE &arg...)
QString & replace(int position, int n, QChar after)
KGuiItem yes()
int startTimer(int interval, Qt::TimerType timerType)
static QString proxyForUrl(const QUrl &url)
QString mid(int position, int n) const const
KIOFILEWIDGETS_EXPORT QString dir(const QString &fileClass)
QWidget * parentWidget() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString windowTitle() const const
typedef ConstIterator
int height() const const
int length() const const
char * data()
virtual bool processEvents(QEventLoop::ProcessEventsFlags flags)=0
int size() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
void setDefault(bool)
T readEntry(const QString &key, const T &aDefault) const
int count(const Key &key) const const
QList::iterator begin()
QString locate(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options)
void addLayout(QLayout *layout, int stretch)
const QList< QKeySequence > & quit()
virtual bool unregisterTimers(QObject *object)=0
const T value(const Key &key, const T &defaultValue) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Oct 26 2021 22:48:04 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.