diff --git a/sources/3rdparty/task/taskadds.cpp b/sources/3rdparty/task/taskadds.cpp
index 7629c05..0116def 100644
--- a/sources/3rdparty/task/taskadds.cpp
+++ b/sources/3rdparty/task/taskadds.cpp
@@ -29,12 +29,14 @@ TaskResult runTask(const QString cmd, const bool useSuid)
command.waitForFinished(-1);
r.exitCode = command.exitCode();
r.output = command.readAllStandardOutput();
+ r.error = command.readAllStandardError();
} else {
QProcess command;
command.start(cmd);
command.waitForFinished(-1);
r.exitCode = command.exitCode();
r.output = command.readAllStandardOutput();
+ r.error = command.readAllStandardError();
}
return r;
diff --git a/sources/3rdparty/task/taskadds.h b/sources/3rdparty/task/taskadds.h
index 8a49b1e..609fcba 100644
--- a/sources/3rdparty/task/taskadds.h
+++ b/sources/3rdparty/task/taskadds.h
@@ -38,6 +38,7 @@ protected:
struct TaskResult
{
int exitCode;
+ QByteArray error;
QByteArray output;
};
TaskResult runTask(const QString cmd, const bool useSuid = true);
diff --git a/sources/dataengine/netctl.conf b/sources/dataengine/netctl.conf
index c744ea0..40aa930 100644
--- a/sources/dataengine/netctl.conf
+++ b/sources/dataengine/netctl.conf
@@ -2,15 +2,15 @@
## Commands
# command
-CMD=/usr/bin/netctl
+NETCTLCMD=/usr/bin/netctl
# netctl-auto command
NETCTLAUTOCMD=/usr/bin/netctl-auto
## External IP
# external IPv4 check command
-EXTIPCMD=curl ip4.telize.com
+EXTIP4CMD=curl ip4.telize.com
# 'true' - check external IPv4
-EXTIP=false
+EXTIP4=false
# external IPv6 check command
EXTIP6CMD=curl ip6.telize.com
# 'true' - check external IPv6
diff --git a/sources/gui/docs/CMakeLists.txt b/sources/gui/docs/CMakeLists.txt
index 1569b7f..d9ec0f8 100644
--- a/sources/gui/docs/CMakeLists.txt
+++ b/sources/gui/docs/CMakeLists.txt
@@ -1,9 +1,12 @@
# build pages
file (GLOB SUBPROJECT_DOCS_IN *.html)
+file (GLOB SUBPROJECT_IMGS *.png)
foreach (DOC_IN ${SUBPROJECT_DOCS_IN})
file (RELATIVE_PATH ONE_DOC ${CMAKE_SOURCE_DIR} ${DOC_IN})
configure_file (${DOC_IN} ${CMAKE_CURRENT_BINARY_DIR}/${ONE_DOC})
set (SUBPROJECT_DOCS ${SUBPROJECT_DOCS} ${CMAKE_CURRENT_BINARY_DIR}/${ONE_DOC})
endforeach ()
+
install (FILES ${SUBPROJECT_DOCS} DESTINATION share/doc/${PROJECT_NAME})
+install (FILES ${SUBPROJECT_IMGS} DESTINATION share/doc/${PROJECT_NAME})
diff --git a/sources/gui/docs/architecture.png b/sources/gui/docs/architecture.png
new file mode 100644
index 0000000..ef2424a
Binary files /dev/null and b/sources/gui/docs/architecture.png differ
diff --git a/sources/gui/docs/netctl-gui-security-notes.html b/sources/gui/docs/netctl-gui-security-notes.html
index a715704..a76781e 100644
--- a/sources/gui/docs/netctl-gui-security-notes.html
+++ b/sources/gui/docs/netctl-gui-security-notes.html
@@ -8,11 +8,68 @@
netctl-gui security notes
Project version : @PROJECT_VERSION@
+ - Description
+ - Architecture
+ - KDE components security
+ - Graphical interface security
+ - Library security
+ - Helper security
+
- External links
+Description
+
+
+Architecture
+
+
+KDE components security
+There are two netctl-based commands which are run from the DataEngine
+
+ <cmd> list
+ netctl is-enabled <profile>
+
+Both of them do not require any additional privileges normally. Also DataEngine has two other command which will be run from; they should define external IP. According to the idea that user can set any command to run, this module is not secure. But running commands will not do more than user can do from console himself.
+
+The widget gets information from DataEngine, thus it does not require any additional permissions to show information. But netctl calls with root privileges are used to control netctl. In this case used commands are
+
+ netctl enable <profile>
+ netctl disable <profile>
+ netctl restart <profile>
+ netctl start <profile>
+ netctl stop <profile>
+ netctl switch-to <profile>
+ netctl-auto switch-to <profile>
+
+All netctl-based commands requires root privileges and sudo
(and any other alternatives) is used normally as prefix to the commands. The netctl-auto command does not require additional permissions.
+
+The other way is to use DBus communication with the helper. In this case user should have rights to start the helper.
+
+Graphical interface security
+Graphical interface may interact with netctl over DBus (the helper) and over the library. Please refer to their notes to any additional information. If user uses helper he should have permissions to run it.
+
+Library security
+According to the scheme library gets information from netctl and can control it. Also it provides some additional functions such as a profile creation and removal and access to wpa_supplicant functions. Some function does not require additional permissions, but other ones do it. All dynamic arguments including profile names and paths are in double quotes to avoid white spaces problem. The functions which requires root privileges are:
+
+ - Netctl control module
+
+ netctl start|stop|restart|switch-to|enable|disable <profile>
. They are commands which provide a general control to netctl.
+ systemctl start|restart|enable <netctl-auto@service>
. They are commands which provide ability to control netctl-auto systemd service.
+
+ - Netctl profiles module
+
+ - Copying of a temporary profile from home directory to netctl profiles directory.
cp
command is used for it.
+ - Removal of a profile.
rm
command is used for it.
+
+ - WiFi module
+
+ - This module require root privileges to start wpa_supplicant only. For the futher interaction user must be in
CTRL_GROUP
.
+
+
+
External links
- Homepage
diff --git a/sources/gui/docs/netctl-gui-security-notes.html~ b/sources/gui/docs/netctl-gui-security-notes.html~
new file mode 100644
index 0000000..866453a
--- /dev/null
+++ b/sources/gui/docs/netctl-gui-security-notes.html~
@@ -0,0 +1,88 @@
+
+
+
+ netctl-gui secutiry notes
+
+ netctl-gui security notes
+ Project version : @PROJECT_VERSION@
+
+ - Description
+ - Architecture
+ - KDE components security
+ - Graphical interface security
+ - Library security
+ - Helper security
+
+ - External links
+
+
+
+
+Description
+
+
+Architecture
+
+
+KDE components security
+There are two netctl-based commands which are run from the DataEngine
+
+ <cmd> list
+ netctl is-enabled <profile>
+
+Both of them do not require any additional privileges normally. Also DataEngine has two other command which will be run from; they should define external IP. According to the idea that user can set any command to run, this module is not secure. But running commands will not do more than user can do from console himself.
+
+The widget gets information from DataEngine, thus it does not require any additional permissions to show information. But netctl calls with root privileges are used to control netctl. In this case used commands are
+
+ netctl enable <profile>
+ netctl disable <profile>
+ netctl restart <profile>
+ netctl start <profile>
+ netctl stop <profile>
+ netctl switch-to <profile>
+ netctl-auto switch-to <profile>
+
+All netctl-based commands requires root privileges and sudo
(and any other alternatives) is used normally as prefix to the commands. The netctl-auto command does not require additional permissions.
+
+The other way is to use DBus communication with the helper. In this case user should have rights to start the helper.
+
+Graphical interface security
+Graphical interface may interact with netctl over DBus (the helper) and over the library. Please refer to their notes to any additional information. If user uses helper he should have permissions to run it.
+
+Library security
+According to the scheme library gets information from netctl and can control it. Also it provides some additional functions such as a profile creation and removal and access to wpa_supplicant functions. Some function does not require additional permissions, but other ones do it. All dynamic arguments including profile names and paths are in double quotes to avoid white spaces problem. The functions which requires root privileges are:
+
+ - Netctl control module
+
+ netctl start|stop|restart|switch-to|enable|disable <profile>
. They are commands which provide a general control to netctl.
+ systemctl start|restart|enable <netctl-auto@service>
. They are commands which provide ability to control netctl-auto systemd service.
+
+ - Netctl profiles module
+
+ - Copying of a temporary profile from home directory to netctl profiles directory.
cp
command is used for it.
+ - Removal of a profile.
rm
command is used for it.
+
+ - WiFi module
+
+ - This module require root privileges to start wpa_supplicant only. For the futher interaction user must be in
CTRL_GROUP
.
+
+
+
+
+
+External links
+
+
+
+ © 2014-@CURRENT_YEAR@ @PROJECT_AUTHOR@
+ This software is licensed under @PROJECT_LICENSE@
+
+
+
+
\ No newline at end of file
diff --git a/sources/gui/src/mainpublicslots.cpp b/sources/gui/src/mainpublicslots.cpp
index 973a427..fe4e8e8 100644
--- a/sources/gui/src/mainpublicslots.cpp
+++ b/sources/gui/src/mainpublicslots.cpp
@@ -137,14 +137,24 @@ bool MainWindow::startProfileSlot(const QString profile)
if (useHelper) {
QList args;
args.append(profile);
- sendDBusRequest(DBUS_HELPER_SERVICE, DBUS_CTRL_PATH,
- DBUS_HELPER_INTERFACE, QString("Start"),
- args, true, debug);
+ if (sendDBusRequest(DBUS_HELPER_SERVICE, DBUS_LIB_PATH,
+ DBUS_HELPER_INTERFACE, QString("ActiveProfile"),
+ QList(), true, debug)[0].toString().isEmpty())
+ sendDBusRequest(DBUS_HELPER_SERVICE, DBUS_CTRL_PATH,
+ DBUS_HELPER_INTERFACE, QString("Start"),
+ args, true, debug);
+ else
+ sendDBusRequest(DBUS_HELPER_SERVICE, DBUS_CTRL_PATH,
+ DBUS_HELPER_INTERFACE, QString("SwitchTo"),
+ args, true, debug);
current = sendDBusRequest(DBUS_HELPER_SERVICE, DBUS_LIB_PATH,
DBUS_HELPER_INTERFACE, QString("isProfileActive"),
args, true, debug)[0].toBool();
} else {
- netctlCommand->startProfile(profile);
+ if (netctlCommand->getActiveProfile().isEmpty())
+ netctlCommand->startProfile(profile);
+ else
+ netctlCommand->switchToProfile(profile);
current = netctlCommand->isProfileActive(profile);
}
@@ -328,7 +338,6 @@ void MainWindow::updateConfiguration(const QMap args)
qApp->installTranslator(translator);
createObjects();
- checkHelperStatus();
createActions();
// tray
diff --git a/sources/gui/src/mainwindow.cpp b/sources/gui/src/mainwindow.cpp
index 88b480f..99c7b09 100644
--- a/sources/gui/src/mainwindow.cpp
+++ b/sources/gui/src/mainwindow.cpp
@@ -294,6 +294,8 @@ bool MainWindow::checkHelperStatus()
sendDBusRequest(DBUS_HELPER_SERVICE, DBUS_CTRL_PATH,
DBUS_HELPER_INTERFACE, QString("Update"),
QList(), true, debug);
+ else
+ configuration[QString("FORCE_SUDO")] = QString("true");
if (isHelperServiceActive())
configuration[QString("CLOSE_HELPER")] = QString("false");
@@ -401,6 +403,7 @@ void MainWindow::createObjects()
errorWin->showWindow(19, QString("[MainWindow] : [createObjects]"));
useHelper = false;
}
+ checkHelperStatus();
netctlCommand = new Netctl(debug, configuration);
netctlProfile = new NetctlProfile(debug, configuration);
diff --git a/sources/helper/netctlgui-helper.service b/sources/helper/netctlgui-helper.service
index 2f79121..99b16a8 100644
--- a/sources/helper/netctlgui-helper.service
+++ b/sources/helper/netctlgui-helper.service
@@ -2,6 +2,7 @@
Description=netctlgui-helper daemon
[Service]
+Type=forking
ExecStart=/usr/bin/netctlgui-helper
[Install]
diff --git a/sources/netctlgui/include/netctlgui/wpasupinteract.h b/sources/netctlgui/include/netctlgui/wpasupinteract.h
index 5b28027..256f291 100644
--- a/sources/netctlgui/include/netctlgui/wpasupinteract.h
+++ b/sources/netctlgui/include/netctlgui/wpasupinteract.h
@@ -71,6 +71,7 @@ public:
* @param settings default settings. Needed keys are
* CTRL_DIR (path to ctrl_directory),
* CTRL_GROUP (group which is owner of CTRL_DIR),
+ * FORCE_SUDO (force to use sudo),
* PID_FILE (wpa_supplicant PID file),
* SUDO_PATH (path to sudo command),
* WPACLI_PATH (path to wpa_cli command),
diff --git a/sources/netctlgui/src/netctlinteract.cpp b/sources/netctlgui/src/netctlinteract.cpp
index e2ef7ca..bea09c4 100644
--- a/sources/netctlgui/src/netctlinteract.cpp
+++ b/sources/netctlgui/src/netctlinteract.cpp
@@ -97,10 +97,12 @@ bool Netctl::cmdCall(const bool sudo, const QString command, const QString comma
cmd = sudoCommand + QString(" ");
cmd += command + QString(" ") + commandLine;
if (argument != 0)
- cmd += QString(" ") + argument;
+ cmd += QString(" \"") + argument + QString("\"");
if (debug) qDebug() << "[Netctl]" << "[cmdCall]" << ":" << "Run cmd" << cmd;
TaskResult process = runTask(cmd, (useSuid && sudo));
if (debug) qDebug() << "[Netctl]" << "[cmdCall]" << ":" << "Cmd returns" << process.exitCode;
+ if (process.exitCode != 0)
+ if (debug) qDebug() << "[Netctl]" << "[cmdCall]" << ":" << "Error" << process.error;
if (process.exitCode == 0)
return true;
@@ -128,10 +130,12 @@ QString Netctl::getCmdOutput(const bool sudo, const QString command, const QStri
cmd = sudoCommand + QString(" ");
cmd += command + QString(" ") + commandLine;
if (argument != 0)
- cmd += QString(" ") + argument;
+ cmd += QString(" \"") + argument + QString("\"");
if (debug) qDebug() << "[Netctl]" << "[getCmdOutput]" << ":" << "Run cmd" << cmd;
TaskResult process = runTask(cmd, (useSuid && sudo));
if (debug) qDebug() << "[Netctl]" << "[getCmdOutput]" << ":" << "Cmd returns" << process.exitCode;
+ if (process.exitCode != 0)
+ if (debug) qDebug() << "[Netctl]" << "[getCmdOutput]" << ":" << "Error" << process.error;
return process.output;
}
diff --git a/sources/netctlgui/src/netctlprofile.cpp b/sources/netctlgui/src/netctlprofile.cpp
index c307862..3e5f820 100644
--- a/sources/netctlgui/src/netctlprofile.cpp
+++ b/sources/netctlgui/src/netctlprofile.cpp
@@ -80,10 +80,12 @@ bool NetctlProfile::copyProfile(const QString oldPath)
}
QString newPath = profileDirectory->absolutePath() + QDir::separator() + QFileInfo(oldPath).fileName();
- QString cmd = sudoCommand + QString(" /usr/bin/mv ") + oldPath + QString(" ") + newPath;
+ QString cmd = sudoCommand + QString(" /usr/bin/mv \"") + oldPath + QString("\" \"") + newPath + QString("\"");
if (debug) qDebug() << "[NetctlProfile]" << "[copyProfile]" << ":" << "Run cmd" << cmd;
TaskResult process = runTask(cmd, useSuid);
if (debug) qDebug() << "[NetctlProfile]" << "[copyProfile]" << ":" << "Cmd returns" << process.exitCode;
+ if (process.exitCode != 0)
+ if (debug) qDebug() << "[NetctlProfile]" << "[copyProfile]" << ":" << "Error" << process.error;
if (process.exitCode == 0)
return true;
@@ -143,13 +145,13 @@ QMap NetctlProfile::getSettingsFromProfile(const QString profi
// getting variables list
// system variables
- QProcess shell;
QString cmd = QString("env -i bash -c \"set\"");
if (debug) qDebug() << "[NetctlProfile]" << "[getSettingsFromProfile]" << ":" << "Run cmd" << cmd;
- shell.start(cmd);
- shell.waitForFinished(-1);
- if (debug) qDebug() << "[NetctlProfile]" << "[getSettingsFromProfile]" << ":" << "Cmd returns" << shell.exitCode();
- QStringList output = QString(shell.readAllStandardOutput()).trimmed().split(QChar('\n'));
+ TaskResult process = runTask(cmd, false);
+ if (debug) qDebug() << "[NetctlProfile]" << "[getSettingsFromProfile]" << ":" << "Cmd returns" << process.exitCode;
+ if (process.exitCode != 0)
+ if (debug) qDebug() << "[NetctlProfile]" << "[getSettingsFromProfile]" << ":" << "Error" << process.error;
+ QStringList output = QString(process.output).trimmed().split(QChar('\n'));
QStringList systemVariables;
systemVariables.append(QString("PIPESTATUS"));
for (int i=0; i NetctlProfile::getSettingsFromProfile(const QString profi
// profile variables
QMap settings;
QString profileUrl = profileDirectory->absolutePath() + QDir::separator() + QFileInfo(profile).fileName();
- cmd = QString("env -i bash -c \"source ") + profileUrl + QString("; set\"");
+ cmd = QString("env -i bash -c \"source '") + profileUrl + QString("'; set\"");
if (debug) qDebug() << "[NetctlProfile]" << "[getSettingsFromProfile]" << ":" << "Run cmd" << cmd;
- shell.start(cmd);
- shell.waitForFinished(-1);
- if (debug) qDebug() << "[NetctlProfile]" << "[getSettingsFromProfile]" << ":" << "Cmd returns" << shell.exitCode();
- output = QString(shell.readAllStandardOutput()).trimmed().split(QChar('\n'));
+ process = runTask(cmd, false);
+ if (debug) qDebug() << "[NetctlProfile]" << "[getSettingsFromProfile]" << ":" << "Cmd returns" << process.exitCode;
+ if (process.exitCode != 0)
+ if (debug) qDebug() << "[NetctlProfile]" << "[getSettingsFromProfile]" << ":" << "Error" << process.error;
+ output = QString(process.output).trimmed().split(QChar('\n'));
// gettings variables
QStringList keys;
@@ -170,12 +173,11 @@ QMap NetctlProfile::getSettingsFromProfile(const QString profi
if (!systemVariables.contains(output[i].split(QChar('='))[0]))
keys.append(output[i].split(QChar('='))[0]);
for (int i=0; iabsolutePath() + QDir::separator() + QFileInfo(profile).fileName();
- QString cmd = sudoCommand + QString(" /usr/bin/rm ") + profilePath;
+ QString cmd = sudoCommand + QString(" /usr/bin/rm \"") + profilePath + QString("\"");
if (debug) qDebug() << "[NetctlProfile]" << "[removeProfile]" << ":" << "Run cmd" << cmd;
TaskResult process = runTask(cmd, useSuid);
if (debug) qDebug() << "[NetctlProfile]" << "[removeProfile]" << ":" << "Cmd returns" << process.exitCode;
+ if (process.exitCode != 0)
+ if (debug) qDebug() << "[NetctlProfile]" << "[removeProfile]" << ":" << "Error" << process.error;
if (process.exitCode == 0)
return true;
diff --git a/sources/netctlgui/src/wpasupinteract.cpp b/sources/netctlgui/src/wpasupinteract.cpp
index 21401bf..63171db 100644
--- a/sources/netctlgui/src/wpasupinteract.cpp
+++ b/sources/netctlgui/src/wpasupinteract.cpp
@@ -269,6 +269,8 @@ bool WpaSup::startWpaSupplicant()
TaskResult process = runTask(cmd, useSuid);
waitForProcess(1);
if (debug) qDebug() << "[WpaSup]" << "[startWpaSupplicant]" << ":" << "Cmd returns" << process.exitCode;
+ if (process.exitCode != 0)
+ if (debug) qDebug() << "[WpaSup]" << "[startWpaSupplicant]" << ":" << "Error" << process.error;
if (process.exitCode == 0)
return true;
@@ -324,6 +326,8 @@ QString WpaSup::getWpaCliOutput(const QString commandLine)
if (debug) qDebug() << "[WpaSup]" << "[getWpaCliOutput]" << ":" << "Run cmd" << cmd;
TaskResult process = runTask(cmd);
if (debug) qDebug() << "[WpaSup]" << "[getWpaCliOutput]" << ":" << "Cmd returns" << process.exitCode;
+ if (process.exitCode != 0)
+ if (debug) qDebug() << "[WpaSup]" << "[getWpaCliOutput]" << ":" << "Error" << process.error;
return process.output;
}
@@ -380,6 +384,8 @@ bool WpaSup::wpaCliCall(const QString commandLine)
TaskResult process = runTask(cmd);
waitForProcess(1);
if (debug) qDebug() << "[WpaSup]" << "[getWpaCliOutput]" << ":" << "Cmd returns" << process.exitCode;
+ if (process.exitCode != 0)
+ if (debug) qDebug() << "[NetctlProfile]" << "[getWpaCliOutput]" << ":" << "Error" << process.error;
if (process.exitCode == 0)
return true;
diff --git a/sources/plasmoid/netctl.cpp b/sources/plasmoid/netctl.cpp
index 444be38..0b5aa73 100644
--- a/sources/plasmoid/netctl.cpp
+++ b/sources/plasmoid/netctl.cpp
@@ -907,7 +907,6 @@ void Netctl::configChanged()
if (useHelper) startHelper();
checkHelperStatus();
connectToEngine();
- setAssociatedApplication(paths[QString("gui")]);
}