Fix tsak housekeeping

Provide GUI warning when tsak cannot be used due to system module problems
pull/2/head
Timothy Pearson 12 years ago
parent 8abe81cec2
commit 6cfb160836

@ -21,7 +21,9 @@
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <tqbuttongroup.h>
#include <tqlabel.h>
@ -47,11 +49,14 @@
#include "tdm-appear.h"
#include "kbackedcombobox.h"
#include "config.h"
extern KSimpleConfig *config;
#define TSAK_LOCKFILE "/tmp/tdesocket-global/tsak.lock"
TDMAppearanceWidget::TDMAppearanceWidget(TQWidget *parent, const char *name)
: TQWidget(parent, name)
: TQWidget(parent, name), sakwarning(0)
{
TQString wtstr;
@ -247,6 +252,13 @@ TDMAppearanceWidget::TDMAppearanceWidget(TQWidget *parent, const char *name)
TQGridLayout *hbox2 = new TQGridLayout( group->layout(), 2, 2, KDialog::spacingHint() );
hbox2->setColStretch(1, 1);
hbox2->addWidget(sakbox, 1, 0);
if (getuid() == 0 && config->checkConfigFilesWritable( true )) {
if (system(KDE_BINDIR "/tsak checkdeps") != 0) {
sakbox->setEnabled(false);
sakwarning = new TQLabel( i18n("Secure Attention Key support is not available on your system. Please check for the presence of evdev and uinput."), group );
hbox2->addWidget(sakwarning, 2, 0);
}
}
wtstr = i18n("Here you can enable or disable the Secure Attention Key [SAK] anti-spoofing measure.");
TQWhatsThis::add( sakbox, wtstr );
@ -465,6 +477,21 @@ void TDMAppearanceWidget::save()
config->writeEntry("Language", langcombo->current());
config->writeEntry("UseSAK", sakbox->isChecked());
// Enable/disable tsak as needed
if (sakbox->isChecked()) {
system(KDE_BINDIR "/tsak");
}
else {
// Get PID
TQFile file(TSAK_LOCKFILE);
if (file.open(IO_ReadOnly)) {
TQTextStream stream(&file);
unsigned long tsakpid = stream.readLine().toULong();
file.close();
kill(tsakpid, SIGTERM);
}
}
}
@ -516,7 +543,12 @@ void TDMAppearanceWidget::load()
langcombo->setCurrentItem(config->readEntry("Language", "C"));
// See if the SAK is enabled
if (sakwarning) {
sakbox->setChecked(config->readBoolEntry("UseSAK", true));
}
else {
sakbox->setChecked(false);
}
}

@ -91,6 +91,7 @@ private:
KBackedComboBox *echocombo;
KLanguageButton *langcombo;
TQCheckBox *sakbox;
TQLabel *sakwarning;
};

@ -21,6 +21,7 @@ License along with tsak. If not, see http://www.gnu.org/licenses/.
#include <stdio.h>
#include <stdlib.h>
#include <exception>
#include <string.h>
#include <unistd.h>
#include <errno.h>
@ -38,6 +39,8 @@ License along with tsak. If not, see http://www.gnu.org/licenses/.
#include <libudev.h>
#include <libgen.h>
using namespace std;
#define FIFO_DIR "/tmp/tdesocket-global"
#define FIFO_FILE_OUT "/tmp/tdesocket-global/tsak"
#define FIFO_LOCKFILE_OUT "/tmp/tdesocket-global/tsak.lock"
@ -94,6 +97,38 @@ int bit_set(size_t i, const byte* a)
return a[i/CHAR_BIT] & (1 << i%CHAR_BIT);
}
/* exception handling */
struct exit_exception {
int c;
exit_exception(int c):c(c) { }
};
/* signal handler */
void signal_callback_handler(int signum)
{
// Terminate program
throw exit_exception(signum);
exit(signum);
}
/* termination handler */
void tsak_friendly_termination() {
int i;
// Close down all child processes
for (i=0; i<MAX_KEYBOARDS; i++) {
if (child_pids[i] != 0) {
kill(child_pids[i], SIGTERM);
}
}
// Wait for process termination
sleep(1);
fprintf(stderr, "tsak terminated by external request\n");
exit(17);
}
// --------------------------------------------------------------------------------------
// Useful function from Stack Overflow
// http://stackoverflow.com/questions/874134/find-if-string-endswith-another-string-in-c
@ -258,17 +293,24 @@ bool setupPipe()
return setFileLock(mPipe_fd_out, true);
}
bool setupLockingPipe()
bool setupLockingPipe(bool writepid)
{
/* Create the FIFOs if they do not exist */
umask(0);
mkdir(FIFO_DIR,0644);
mknod(FIFO_LOCKFILE_OUT, S_IFIFO|0600, 0);
mknod(FIFO_LOCKFILE_OUT, 0600, 0);
chmod(FIFO_LOCKFILE_OUT, 0600);
mPipe_lockfd_out = open(FIFO_LOCKFILE_OUT, O_RDWR | O_NONBLOCK);
if (mPipe_lockfd_out > -1) {
if (writepid) {
// Write my PID to the file
pid_t tsakpid = getpid();
char pidstring[1024];
sprintf(pidstring, "%d", tsakpid);
write(mPipe_lockfd_out, pidstring, strlen(pidstring));
}
// Set the exclusive file lock
return setFileLock(mPipe_lockfd_out, true);
}
@ -343,8 +385,8 @@ PipeHandler::~PipeHandler()
{
if (active) {
tearDownPipe();
}
tearDownLockingPipe();
}
}
int main (int argc, char *argv[])
@ -360,12 +402,21 @@ int main (int argc, char *argv[])
bool hide_event = false;
bool established = false;
bool testrun = false;
bool depcheck = false;
int current_keyboard;
bool can_proceed;
// Ignore SIGPIPE
signal(SIGPIPE, SIG_IGN);
// Register signal handlers
// Register signal and signal handler
signal(SIGINT, signal_callback_handler);
signal(SIGTERM, signal_callback_handler);
set_terminate(tsak_friendly_termination);
try {
for (i=0; i<MAX_KEYBOARDS; i++) {
child_pids[i] = 0;
}
@ -374,27 +425,36 @@ int main (int argc, char *argv[])
if (strcmp(argv[1], "checkactive") == 0) {
testrun = true;
}
if (strcmp(argv[1], "checkdeps") == 0) {
depcheck = true;
}
}
if (depcheck == false) {
// Check for existing file locks
if (!checkFileLock()) {
fprintf(stderr, "Another instance of this program is already running [1]\n");
return 8;
}
if (!setupLockingPipe()) {
if (!setupLockingPipe(true)) {
fprintf(stderr, "Another instance of this program is already running [2]\n");
return 8;
}
}
// Create the output pipe
PipeHandler controlpipe;
if (depcheck == false) {
if (!setupPipe()) {
fprintf(stderr, "Another instance of this program is already running\n");
return 8;
}
}
while (1) {
if (depcheck == false) {
controlpipe.active = true;
}
if ((getuid ()) != 0) {
printf ("You are not root! This WILL NOT WORK!\nDO NOT attempt to bypass security restrictions, e.g. by changing keyboard permissions or owner, if you want the SAK system to remain secure...\n");
@ -405,6 +465,9 @@ int main (int argc, char *argv[])
find_keyboards();
if (keyboard_fd_num == 0) {
printf ("Could not find any usable keyboard(s)!\n");
if (depcheck == true) {
return 50;
}
// Make sure everyone knows we physically can't detect a SAK
// Before we do this we broadcast one so that active dialogs are updated appropriately
// Also, we keep watching for a keyboard to be added via a forked child process...
@ -450,6 +513,9 @@ int main (int argc, char *argv[])
return 3;
}
}
if (depcheck == true) {
return 0;
}
if (can_proceed == true) {
for (current_keyboard=0;current_keyboard<keyboard_fd_num;current_keyboard++) {
@ -488,7 +554,7 @@ int main (int argc, char *argv[])
child_pids[current_keyboard] = i;
continue;
}
setupLockingPipe();
setupLockingPipe(false);
}
established = true;
@ -565,7 +631,7 @@ int main (int argc, char *argv[])
}
// Prevent multiple process instances from starting
setupLockingPipe();
setupLockingPipe(true);
// Wait a little bit so that udev hotplug can stabilize before we start monitoring
sleep(1);
@ -645,6 +711,10 @@ int main (int argc, char *argv[])
}
}
}
}
catch(exit_exception& e) {
exit(e.c);
}
return 6;
}

Loading…
Cancel
Save