Commit 7dec2a62 authored by Thomas Friedrichsmeier's avatar Thomas Friedrichsmeier
Browse files

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)
parent 0999198f
- 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
......
......@@ -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@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"));
......
......@@ -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@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"
......@@ -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@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
......@@ -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..."));
......
......@@ -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:
......
......@@ -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@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;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment