[rkward] /: Warn before starting plugins specified on the command line.

Thomas Friedrichsmeier thomas.friedrichsmeier at ruhr-uni-bochum.de
Mon Dec 7 19:33:02 UTC 2015


Git commit 7dec2a621e2ea74ed380201a8084ec30ec49da1d by Thomas Friedrichsmeier.
Committed on 07/12/2015 at 19:31.
Pushed by tfry into branch 'master'.

Warn before starting plugins specified on the command line.

(Warning can also be turned off, via a command-line option. This is targetted at foolishly clicking on an rkward://runplugin/-link on an untrusted website)

M  +2    -0    ChangeLog
M  +4    -2    rkward/main.cpp
M  +3    -7    rkward/misc/rkdbusapi.cpp
M  +2    -2    rkward/misc/rkdbusapi.h
M  +33   -10   rkward/rkward.cpp
M  +2    -0    rkward/rkward.h
M  +5    -2    rkward/rkward_startup_wrapper.cpp

http://commits.kde.org/rkward/7dec2a621e2ea74ed380201a8084ec30ec49da1d

diff --git a/ChangeLog b/ChangeLog
index a37abf4..fdf07aa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+- Show a warning screen when invoking plugins from the command line (or from clicking an rkward://-link in an external application)
+
 --- Version 0.6.4 - XXXXXXXXXXXXXXX
 - Fixed: Plugin variable slots taking more than one object would not be hightlighted in red while invalid
 - Plugins check for correct object type, in more places, but allow to proceed with questionable object selections
diff --git a/rkward/main.cpp b/rkward/main.cpp
index c2ce147..2fcbe07 100644
--- a/rkward/main.cpp
+++ b/rkward/main.cpp
@@ -127,6 +127,7 @@ int main(int argc, char *argv[]) {
 	options.add ("backend-debugger <command>", ki18n ("Debugger for the backend. (Enclose any debugger arguments in single quotes ('') together with the command. Make sure to re-direct stdout!)"), "");
 	options.add ("r-executable <command>", ki18n ("Use specified R installation, instead of the one configured at compile time (note: rkward R library must be installed to that installation of R)"), "");
 	options.add ("reuse", ki18n ("Reuse a running RKWard instance (if available). If a running instance is reused, only the file arguments will be interpreted, all other options will be ignored."), 0);
+	options.add ("nowarn-external", ki18n ("When used in conjunction with rkward://runplugin/-URLs specified on the command line, suppresses the warning about application-external (untrusted) links."));
 	options.add ("+[Files]", ki18n ("File or files to open, typically a workspace, or an R script file. When loading several things, you should specify the workspace, first."), 0);
 
 	KAboutData aboutData("rkward", QByteArray (), ki18n ("RKWard"), RKWARD_VERSION, ki18n ("Frontend to the R statistics language"), KAboutData::License_GPL, ki18n ("(c) 2002, 2004 - 2014"), KLocalizedString (), "http://rkward.kde.org", "submit at bugs.kde.org");
@@ -172,11 +173,12 @@ int main(int argc, char *argv[]) {
 	}
 
 	if (args->count ()) {
-		QVariantList urls_to_open;
+		QStringList urls_to_open;
 		for (int i = 0; i < args->count (); ++i) {
-			urls_to_open.append (QUrl (KCmdLineArgs::makeURL (decodeArgument (args->arg (i)).toUtf8 ())));
+			urls_to_open.append (KCmdLineArgs::makeURL (decodeArgument (args->arg (i)).toUtf8 ()).url ());
 		}
 		RKGlobals::startup_options["initial_urls"] = urls_to_open;
+		RKGlobals::startup_options["warn_external"] = args->isSet ("warn-external");
 	}
 	RKGlobals::startup_options["evaluate"] = decodeArgument (args->getOption ("evaluate"));
 	RKGlobals::startup_options["backend-debugger"] = decodeArgument (args->getOption ("backend-debugger"));
diff --git a/rkward/misc/rkdbusapi.cpp b/rkward/misc/rkdbusapi.cpp
index 4924ba9..3ec6fa4 100644
--- a/rkward/misc/rkdbusapi.cpp
+++ b/rkward/misc/rkdbusapi.cpp
@@ -2,7 +2,7 @@
                           rkdbusapi  -  description
                              -------------------
     begin                : Thu Nov 20 2014
-    copyright            : (C) 2014 by Thomas Friedrichsmeier
+    copyright            : (C) 2014, 2015 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -40,7 +40,7 @@ RKDBusAPI::RKDBusAPI (QObject* parent): QObject (parent) {
 	QDBusConnection::sessionBus ().registerObject ("/", this, QDBusConnection::ExportScriptableSlots);
 }
 
-void RKDBusAPI::openAnyUrl(const QStringList& urls) {
+void RKDBusAPI::openAnyUrl (const QStringList& urls, bool warn_external) {
 	RK_TRACE (APP);
 
 	// ok, raising the app window is totally hard to do, reliably. This solution copied from kate.
@@ -55,11 +55,7 @@ void RKDBusAPI::openAnyUrl(const QStringList& urls) {
 #endif
 	// end
 
-	RKWardMainWindow::getMain ()->setMergeLoads (true);
-	for (int i = 0; i < urls.size (); ++i) {
-		RKWorkplace::mainWorkplace ()->openAnyUrl (urls[i]);
-	}
-	RKWardMainWindow::getMain ()->setMergeLoads (false);
+	RKWardMainWindow::getMain ()->openUrlsFromCommandLineOrDBus (warn_external, urls);
 }
 
 #include "rkdbusapi.moc"
diff --git a/rkward/misc/rkdbusapi.h b/rkward/misc/rkdbusapi.h
index d95d6ed..73376ff 100644
--- a/rkward/misc/rkdbusapi.h
+++ b/rkward/misc/rkdbusapi.h
@@ -2,7 +2,7 @@
                           rkdbusapi  -  description
                              -------------------
     begin                : Thu Nov 20 2014
-    copyright            : (C) 2014 by Thomas Friedrichsmeier
+    copyright            : (C) 2014, 2015 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -29,7 +29,7 @@ public:
 	explicit RKDBusAPI (QObject *parent);
 	~RKDBusAPI () {};
 public slots:
-	Q_SCRIPTABLE void openAnyUrl (const QStringList &urls);
+	Q_SCRIPTABLE void openAnyUrl (const QStringList &urls, bool warn_external=true);
 };
 
 #endif
diff --git a/rkward/rkward.cpp b/rkward/rkward.cpp
index e07c560..ee13bf0 100644
--- a/rkward/rkward.cpp
+++ b/rkward/rkward.cpp
@@ -197,7 +197,8 @@ void RKWardMainWindow::doPostInit () {
 		KMessageBox::error (this, i18n ("<p>RKWard either could not find its resource files at all, or only an old version of those files. The most likely cause is that the last installation failed to place the files in the correct place. This can lead to all sorts of problems, from single missing features to complete failure to function.</p><p><b>You should quit RKWard, now, and fix your installation</b>. For help with that, see <a href=\"http://rkward.kde.org/compiling\">http://rkward.kde.org/compiling</a>.</p>"), i18n ("Broken installation"), KMessageBox::Notify | KMessageBox::AllowLink);
 	}
 
-	QVariantList open_urls = RKGlobals::startup_options.take ("initial_urls").toList ();
+	QStringList open_urls = RKGlobals::startup_options.take ("initial_urls").toStringList ();
+	bool warn_external = RKGlobals::startup_options.take ("warn_external").toBool ();
 	QString evaluate_code = RKGlobals::startup_options.take ("evaluate").toString ();
 
 	initPlugins ();
@@ -216,22 +217,21 @@ void RKWardMainWindow::doPostInit () {
 		}
 	}
 #endif
+	KMessageBox::enableMessage ("external_link_warning");
 
 	KUrl recover_url = RKRecoverDialog::checkRecoverCrashedWorkspace ();
 	if (!recover_url.isEmpty ()) {
-		open_urls.clear ();
-		open_urls.append (recover_url);		// Well, not a perfect solution. But we certainly don't want to overwrite the just recovered workspace.
+		open_urls.clear ();    // Well, not a perfect solution. But we certainly don't want to overwrite the just recovered workspace.
+		open_urls.append (recover_url.url ());
 	}
 
-	setMergeLoads (true);
 	for (int i = 0; i < open_urls.size (); ++i) {
 		// make sure local urls are absolute, as we may be changing wd before loading
-		KUrl url = open_urls[i].toUrl ();
+		KUrl url = open_urls[i];
 		if (url.isRelative ()) {
-			open_urls[i] = KUrl::fromLocalFile (QDir::current ().absoluteFilePath (url.toLocalFile ()));
+			open_urls[i] = QDir::current ().absoluteFilePath (url.toLocalFile ());
 		}
 	}
-	setMergeLoads (false);
 
 	QString cd_to = RKSettingsModuleGeneral::initialWorkingDirectory ();
 	if (!cd_to.isEmpty ()) {
@@ -243,9 +243,7 @@ void RKWardMainWindow::doPostInit () {
 		// the help window will be on top
 		if (RKSettingsModuleGeneral::showHelpOnStartup ()) toplevel_actions->showRKWardHelp ();
 
-		for (int i = 0; i < open_urls.size (); ++i) {
-			RKWorkplace::mainWorkplace ()->openAnyUrl (open_urls[i].toUrl ());
-		}
+		openUrlsFromCommandLineOrDBus (warn_external, open_urls);
 	} else {
 		StartupDialog::StartupDialogResult result = StartupDialog::getStartupAction (this, fileOpenRecentWorkspace);
 		if (!result.open_url.isEmpty ()) {
@@ -278,6 +276,31 @@ void RKWardMainWindow::doPostInit () {
 	setCaption (QString ());	// our version of setCaption takes care of creating a correct caption, so we do not need to provide it here
 }
 
+void RKWardMainWindow::openUrlsFromCommandLineOrDBus (bool warn_external, QStringList urls) {
+	RK_TRACE (APP);
+
+	bool any_dangerous_urls = false;
+	for (int i = 0; i < urls.size (); ++i) {
+		QUrl url = urls[i];
+		if (url.scheme () == "rkward" && url.host () == "runplugin") {
+			any_dangerous_urls = true;
+			break;
+		}
+	}
+
+	if (warn_external && any_dangerous_urls) {
+		RK_ASSERT (urls.size () == 1);
+		QString message = i18n ("<p>You are about to start an RKWard dialog from outside of RKWard, probably by clicking on an 'rkward://'-link, somewhere. In case you have found this link on an external website, please bear in mind that R can be used to run arbitrary commands on your computer, <b>potentially including downloading and installing malicious software</b>. If you do not trust the source of the link you were following, you should press 'Cancel', below.</p><p>In case you click 'Continue', no R code will be run, unless and until you click 'Submit' in the dialog window, and you are encouraged to review the generated R code, before doing so.</p><p><i>Note</i>: Checking 'Do not ask again' will suppress this message for the remainder of this session, only.");
+		if (KMessageBox::warningContinueCancel (this, message, i18n ("A note on external links"), KStandardGuiItem::cont (), KStandardGuiItem::cancel (), "external_link_warning") != KMessageBox::Continue) return;
+	}
+
+	RKWardMainWindow::getMain ()->setMergeLoads (true);
+	for (int i = 0; i < urls.size (); ++i) {
+		RKWorkplace::mainWorkplace ()->openAnyUrl (urls[i], QString (), false);
+	}
+	RKWardMainWindow::getMain ()->setMergeLoads (false);
+}
+
 void RKWardMainWindow::initPlugins (const QStringList &automatically_added) {
 	RK_TRACE (APP);
 	slotSetStatusBarText(i18n("Setting up plugins..."));
diff --git a/rkward/rkward.h b/rkward/rkward.h
index b02c6e5..22c7124 100644
--- a/rkward/rkward.h
+++ b/rkward/rkward.h
@@ -133,6 +133,8 @@ public slots:
 	void setCaption (const QString &);
 /** HACK this is only to make the compiler happy with -Woverloaded-virtual */
 	void setCaption (const QString &dummy, bool) { setCaption (dummy); };
+
+	void openUrlsFromCommandLineOrDBus (bool warn_external, QStringList urls);
 private slots:
 	void partChanged (KParts::Part *new_part);
 private:
diff --git a/rkward/rkward_startup_wrapper.cpp b/rkward/rkward_startup_wrapper.cpp
index 6c14e32..b49bcd1 100644
--- a/rkward/rkward_startup_wrapper.cpp
+++ b/rkward/rkward_startup_wrapper.cpp
@@ -2,7 +2,7 @@
                           rkward_startup_wrapper  -  description
                              -------------------
     begin                : Sun Mar 10 2013
-    copyright            : (C) 2013, 2014 by Thomas Friedrichsmeier
+    copyright            : (C) 2013, 2014, 2015 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -107,6 +107,7 @@ int main (int argc, char *argv[]) {
 	QStringList debugger_args;
 	QStringList file_args;
 	bool reuse = false;
+	bool warn_external = true;
 	QString r_exe_arg;
 	int debug_level = 2;
 
@@ -131,6 +132,8 @@ int main (int argc, char *argv[]) {
 			}
 		} else if (args[i] == "--reuse") {
 			reuse = true;
+		} else if (args[i] == "--nowarn-external") {
+			warn_external = false;
 		} else if (args[i].startsWith ("--")) {
 			// all RKWard and KDE options (other than --reuse) are of the for --option <value>. So skip over the <value>
 			i++;
@@ -150,7 +153,7 @@ int main (int argc, char *argv[]) {
 		} else {
 			QDBusInterface iface (RKDBUS_SERVICENAME, "/", "", QDBusConnection::sessionBus ());
 			if (iface.isValid ()) {
-				QDBusReply<void> reply = iface.call ("openAnyUrl", file_args);
+				QDBusReply<void> reply = iface.call ("openAnyUrl", file_args, warn_external);
 				if (!reply.isValid ()) {
 					if (debug_level > 2) qDebug ("Error while placing dbus call: %s", qPrintable (reply.error ().message ()));
 					return 1;



More information about the rkward-tracker mailing list