summaryrefslogtreecommitdiffstats
path: root/tdm
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2015-09-17 17:30:17 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2015-09-17 17:30:17 -0500
commitce477303019c7f3ba18dcab48e4205d59614ce5a (patch)
tree19e49c43c92ba12de306af4f92f3fda64d9e92b8 /tdm
parent5d20ad97bffa56b2e366989e71ac9429116c017d (diff)
downloadtdebase-ce477303019c7f3ba18dcab48e4205d59614ce5a.tar.gz
tdebase-ce477303019c7f3ba18dcab48e4205d59614ce5a.zip
Add initial cryptographic card login support
Tested with themed greeter and SAK disabled
Diffstat (limited to 'tdm')
-rw-r--r--tdm/CMakeLists.txt1
-rw-r--r--tdm/backend/client.c19
-rw-r--r--tdm/cryptocardwatcher/CMakeLists.txt32
-rw-r--r--tdm/cryptocardwatcher/main.cpp139
-rw-r--r--tdm/cryptocardwatcher/watcher.cc86
-rw-r--r--tdm/cryptocardwatcher/watcher.h40
-rw-r--r--tdm/kfrontend/CMakeLists.txt2
-rw-r--r--tdm/kfrontend/kgapp.cpp12
-rw-r--r--tdm/kfrontend/kgreeter.cpp72
-rw-r--r--tdm/kfrontend/kgreeter.h4
-rw-r--r--tdm/kfrontend/kgverify.cpp200
-rw-r--r--tdm/kfrontend/kgverify.h4
-rw-r--r--tdm/kfrontend/themer/tdmitem.cpp21
-rw-r--r--tdm/kfrontend/themer/tdmitem.h1
-rw-r--r--tdm/kfrontend/themer/tdmlabel.h6
-rw-r--r--tdm/kfrontend/themer/tdmthemer.cpp6
-rw-r--r--tdm/kfrontend/themer/tdmthemer.h1
-rw-r--r--tdm/kfrontend/themes/circles/circles.xml4
-rw-r--r--tdm/kfrontend/themes/minimalist/minimalist.xml4
-rw-r--r--tdm/kfrontend/themes/o2_enterprise/enterprise.xml4
20 files changed, 577 insertions, 81 deletions
diff --git a/tdm/CMakeLists.txt b/tdm/CMakeLists.txt
index 08096f84..ce8a1f4e 100644
--- a/tdm/CMakeLists.txt
+++ b/tdm/CMakeLists.txt
@@ -21,3 +21,4 @@ include( ConfigureChecks.cmake )
add_subdirectory( backend )
add_subdirectory( kfrontend )
+add_subdirectory( cryptocardwatcher )
diff --git a/tdm/backend/client.c b/tdm/backend/client.c
index cb185bca..2676a5d2 100644
--- a/tdm/backend/client.c
+++ b/tdm/backend/client.c
@@ -180,7 +180,7 @@ PAM_conv( int num_msg,
ReInitErrorLog();
Debug( "PAM_conv\n" );
- for (count = 0; count < num_msg; count++)
+ for (count = 0; count < num_msg; count++) {
switch (msg[count]->msg_style) {
case PAM_TEXT_INFO:
Debug( " PAM_TEXT_INFO: %s\n", msg[count]->msg );
@@ -201,9 +201,18 @@ PAM_conv( int num_msg,
/* case PAM_PROMPT_ECHO_ON: cannot happen */
case PAM_PROMPT_ECHO_OFF:
Debug( " PAM_PROMPT_ECHO_OFF (usecur): %s\n", msg[count]->msg );
- if (!curpass)
- pd->gconv( GCONV_PASS, 0 );
- StrDup( &reply[count].resp, curpass );
+ // WARNING
+ // This is far from foolproof, but it's the best we can do at this time...
+ // Try to detect PIN entry requests
+ if (strstr(msg[count]->msg, "PIN")) {
+ reply[count].resp = pd->gconv(GCONV_HIDDEN, msg[count]->msg);
+ }
+ else {
+ if (!curpass) {
+ pd->gconv( GCONV_PASS, 0 );
+ }
+ StrDup( &reply[count].resp, curpass );
+ }
break;
default:
LogError( "Unknown PAM message style <%d>\n", msg[count]->msg_style );
@@ -237,6 +246,7 @@ PAM_conv( int num_msg,
}
reply[count].resp_retcode = PAM_SUCCESS; /* unused in linux-pam */
}
+ }
Debug( " PAM_conv success\n" );
*resp = reply;
return PAM_SUCCESS;
@@ -769,7 +779,6 @@ Verify( GConvFunc gconv, int rootok )
}
#ifdef USE_PAM
-
Debug( " pam_acct_mgmt() ...\n" );
pretc = pam_acct_mgmt( pamh, 0 );
ReInitErrorLog();
diff --git a/tdm/cryptocardwatcher/CMakeLists.txt b/tdm/cryptocardwatcher/CMakeLists.txt
new file mode 100644
index 00000000..7564ac2c
--- /dev/null
+++ b/tdm/cryptocardwatcher/CMakeLists.txt
@@ -0,0 +1,32 @@
+#################################################
+#
+# (C) 2015 Timothy Pearson
+# kb9vqf (AT) pearsoncomputing.net
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/tdmlib
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### tdecryptocardwatcher (executable) #########
+
+tde_add_executable( tdecryptocardwatcher AUTOMOC
+ SOURCES main.cpp watcher.cc
+ LINK tdecore-shared tdeio-shared dmctl-static
+ DESTINATION ${BIN_INSTALL_DIR}
+ SETUID
+)
+
diff --git a/tdm/cryptocardwatcher/main.cpp b/tdm/cryptocardwatcher/main.cpp
new file mode 100644
index 00000000..5d27ff19
--- /dev/null
+++ b/tdm/cryptocardwatcher/main.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
+ *
+ * This file is part of cryptocardwatcher, the TDE Cryptographic Card Session Monitor
+ *
+ * cryptocardwatcher is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * cryptocardwatcher is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with cryptocardwatcher. 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>
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <termios.h>
+#include <signal.h>
+#include <stdint.h>
+
+#include <tqobject.h>
+
+#include <tdeapplication.h>
+#include <tdecmdlineargs.h>
+
+#include <ksslcertificate.h>
+
+#include <tdehardwaredevices.h>
+#include <tdecryptographiccarddevice.h>
+
+#include "watcher.h"
+
+int lockfd = -1;
+char lockFileName[256];
+
+// --------------------------------------------------------------------------------------
+// Useful function from Stack Overflow
+// http://stackoverflow.com/questions/1599459/optimal-lock-file-method
+// --------------------------------------------------------------------------------------
+int tryGetLock(char const *lockName) {
+ mode_t m = umask( 0 );
+ int fd = open( lockName, O_RDWR|O_CREAT, 0666 );
+ umask( m );
+ if( fd >= 0 && flock( fd, LOCK_EX | LOCK_NB ) < 0 ) {
+ close( fd );
+ fd = -1;
+ }
+ return fd;
+}
+// --------------------------------------------------------------------------------------
+
+// --------------------------------------------------------------------------------------
+// Useful function from Stack Overflow
+// http://stackoverflow.com/questions/1599459/optimal-lock-file-method
+// --------------------------------------------------------------------------------------
+void releaseLock(int fd, char const *lockName) {
+ if( fd < 0 ) {
+ return;
+ }
+ remove( lockName );
+ close( fd );
+}
+// --------------------------------------------------------------------------------------
+
+void handle_sigterm(int signum) {
+ if (lockfd >= 0) {
+ releaseLock(lockfd, lockFileName);
+ }
+ exit(0);
+}
+
+static TDECmdLineOptions options[] =
+{
+ TDECmdLineLastOption
+};
+
+int main(int argc, char *argv[]) {
+ int ret = -1;
+
+ // Register cleanup handlers
+ struct sigaction action;
+ memset(&action, 0, sizeof(struct sigaction));
+ action.sa_handler = handle_sigterm;
+ sigaction(SIGTERM, &action, NULL);
+
+ // Ensure only one process is running
+ sprintf(lockFileName, "/var/lock/cryptocardwatcher.lock");
+ lockfd = tryGetLock(lockFileName);
+ if (lockfd < 0) {
+ printf ("[cryptocardwatcher] Another instance of this program is already running!\n[cryptocardwatcher] Lockfile detected at '%s'\n", lockFileName);
+ return -2;
+ }
+
+ // Parse command line arguments
+ TDECmdLineArgs::init(argc, argv, "cryptocardwatcher", "cryptocardwatcher", "TDE Cryptographic Card Session Monitor", "0.1");
+ TDECmdLineArgs::addCmdLineOptions(options);
+ TDEApplication::addCmdLineOptions();
+
+ // Initialize TDE application
+ TDEApplication tdeapp(false, false);
+ tdeapp.disableAutoDcopRegistration();
+ CardWatcher* watcher = new CardWatcher();
+
+ // Initialize SmartCard readers
+ TDEGenericDevice *hwdevice;
+ TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
+ TDEGenericHardwareList cardReaderList = hwdevices->listByDeviceClass(TDEGenericDeviceType::CryptographicCard);
+ for (hwdevice = cardReaderList.first(); hwdevice; hwdevice = cardReaderList.next()) {
+ TDECryptographicCardDevice* cdevice = static_cast<TDECryptographicCardDevice*>(hwdevice);
+ TQObject::connect(cdevice, TQT_SIGNAL(cardInserted(TDECryptographicCardDevice*)), watcher, TQT_SLOT(cryptographicCardInserted(TDECryptographicCardDevice*)));
+ TQObject::connect(cdevice, TQT_SIGNAL(cardRemoved(TDECryptographicCardDevice*)), watcher, TQT_SLOT(cryptographicCardRemoved(TDECryptographicCardDevice*)));
+ cdevice->enableCardMonitoring(true);
+ }
+
+ // Start TDE application
+ ret = tdeapp.exec();
+
+ // Clean up
+ delete watcher;
+
+ releaseLock(lockfd, lockFileName);
+ return ret;
+}
diff --git a/tdm/cryptocardwatcher/watcher.cc b/tdm/cryptocardwatcher/watcher.cc
new file mode 100644
index 00000000..e2582118
--- /dev/null
+++ b/tdm/cryptocardwatcher/watcher.cc
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
+ *
+ * This file is part of cryptocardwatcher, the TDE Cryptographic Card Session Monitor
+ *
+ * cryptocardwatcher is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * cryptocardwatcher is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with cryptocardwatcher. If not, see http://www.gnu.org/licenses/.
+ */
+
+#include "watcher.h"
+
+#include <ksslcertificate.h>
+
+#include <tdehardwaredevices.h>
+#include <tdecryptographiccarddevice.h>
+
+#include <dmctl.h>
+#include <kuser.h>
+
+CardWatcher::CardWatcher() : TQObject() {
+ //
+}
+
+CardWatcher::~CardWatcher() {
+ //
+}
+
+void CardWatcher::cryptographicCardInserted(TDECryptographicCardDevice* cdevice) {
+ TQString login_name = TQString::null;
+ X509CertificatePtrList certList = cdevice->cardX509Certificates();
+ if (certList.count() > 0) {
+ KSSLCertificate* card_cert = NULL;
+ card_cert = KSSLCertificate::fromX509(certList[0]);
+ TQStringList cert_subject_parts = TQStringList::split("/", card_cert->getSubject(), false);
+ for (TQStringList::Iterator it = cert_subject_parts.begin(); it != cert_subject_parts.end(); ++it ) {
+ TQString lcpart = (*it).lower();
+ if (lcpart.startsWith("cn=")) {
+ login_name = lcpart.right(lcpart.length() - strlen("cn="));
+ }
+ }
+ delete card_cert;
+ }
+
+ if (login_name != "") {
+ // Determine if user already has an active session
+ DM dm;
+ SessList sess;
+ bool user_active = false;
+ if (dm.localSessions(sess)) {
+ TQString user, loc;
+ for (SessList::ConstIterator it = sess.begin(); it != sess.end(); ++it) {
+ DM::sess2Str2(*it, user, loc);
+ if (user.startsWith(login_name + ": ")) {
+ // Found active session
+ user_active = true;
+ }
+ if (user == "Unused") {
+ if ((*it).vt == dm.activeVT()) {
+ // Found active unused session
+ user_active = true;
+ }
+ }
+ }
+ }
+ if (!user_active) {
+ // Activate new VT
+ DM().startReserve();
+ }
+ }
+}
+
+void CardWatcher::cryptographicCardRemoved(TDECryptographicCardDevice* cdevice) {
+ //
+}
+
+#include "watcher.moc" \ No newline at end of file
diff --git a/tdm/cryptocardwatcher/watcher.h b/tdm/cryptocardwatcher/watcher.h
new file mode 100644
index 00000000..bfbb010a
--- /dev/null
+++ b/tdm/cryptocardwatcher/watcher.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
+ *
+ * This file is part of cryptocardwatcher, the TDE Cryptographic Card Session Monitor
+ *
+ * cryptocardwatcher is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * cryptocardwatcher is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with cryptocardwatcher. If not, see http://www.gnu.org/licenses/.
+ */
+
+#ifndef __TDECRYPTOCARDWATCHER_H__
+#define __TDECRYPTOCARDWATCHER_H__
+
+#include <tqobject.h>
+
+class TDECryptographicCardDevice;
+
+class CardWatcher : public TQObject
+{
+ Q_OBJECT
+
+ public:
+ CardWatcher();
+ ~CardWatcher();
+
+ public slots:
+ void cryptographicCardInserted(TDECryptographicCardDevice*);
+ void cryptographicCardRemoved(TDECryptographicCardDevice*);
+};
+
+#endif // __TDECRYPTOCARDWATCHER_H__ \ No newline at end of file
diff --git a/tdm/kfrontend/CMakeLists.txt b/tdm/kfrontend/CMakeLists.txt
index 8c0fffd5..ab2ddc69 100644
--- a/tdm/kfrontend/CMakeLists.txt
+++ b/tdm/kfrontend/CMakeLists.txt
@@ -68,7 +68,7 @@ tde_add_executable( tdm_greet AUTOMOC
kfdialog.cpp kgdialog.cpp kchooser.cpp kgverify.cpp
tdmshutdown.cpp tdmadmindialog.cpp kgreeter.cpp
kgapp.cpp sakdlg.cc
- LINK tdmthemer-static tdeui-shared Xtst ${TDMGREET_OPTIONAL_LINK}
+ LINK tdmthemer-static tdeui-shared tdeio-shared dmctl-static Xtst ${TDMGREET_OPTIONAL_LINK}
DESTINATION ${BIN_INSTALL_DIR}
)
diff --git a/tdm/kfrontend/kgapp.cpp b/tdm/kfrontend/kgapp.cpp
index 2d630485..65e6cf0d 100644
--- a/tdm/kfrontend/kgapp.cpp
+++ b/tdm/kfrontend/kgapp.cpp
@@ -72,6 +72,7 @@ bool has_twin = false;
bool is_themed = false;
bool trinity_desktop_lock_use_sak = TRUE;
bool trinity_desktop_synchronize_keyboard_lights = TRUE;
+bool trinity_desktop_watch_cryptographic_cards = TRUE;
TQPoint primaryScreenPosition;
static int
@@ -216,6 +217,7 @@ kg_main( const char *argv0 )
TDEProcess *tsak = 0;
TDEProcess *kbdl = 0;
+ TDEProcess *ccsm = 0;
TDEProcess *proc = 0;
TDEProcess *comp = 0;
TDEProcess *dcop = 0;
@@ -252,6 +254,12 @@ kg_main( const char *argv0 )
kbdl->start();
}
+ if (trinity_desktop_watch_cryptographic_cards) {
+ ccsm = new TDEProcess;
+ *ccsm << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + "tdecryptocardwatcher";
+ ccsm->start();
+ }
+
XSetErrorHandler( ignoreXError );
argb_visual_available = false;
char *display = 0;
@@ -518,6 +526,10 @@ kg_main( const char *argv0 )
kbdl->closeStdin();
kbdl->detach();
}
+ if (ccsm) {
+ ccsm->closeStdin();
+ ccsm->detach();
+ }
if (comp) {
if (comp->isRunning()) {
if (_compositor == TDE_COMPOSITOR_BINARY) {
diff --git a/tdm/kfrontend/kgreeter.cpp b/tdm/kfrontend/kgreeter.cpp
index aa89fd78..d3ee07de 100644
--- a/tdm/kfrontend/kgreeter.cpp
+++ b/tdm/kfrontend/kgreeter.cpp
@@ -33,6 +33,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "themer/tdmitem.h"
#include "themer/tdmlabel.h"
+#include <dmctl.h>
+
+#include <ksslcertificate.h>
+
+#include <tdehardwaredevices.h>
+#include <tdecryptographiccarddevice.h>
+
#include <tdeapplication.h>
#include <tdelocale.h>
#include <kstandarddirs.h>
@@ -212,6 +219,17 @@ KGreeter::KGreeter( bool framed )
pluginList = KGVerify::init( _pluginsLogin );
}
+ // Initialize SmartCard readers
+ TDEGenericDevice *hwdevice;
+ TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
+ TDEGenericHardwareList cardReaderList = hwdevices->listByDeviceClass(TDEGenericDeviceType::CryptographicCard);
+ for (hwdevice = cardReaderList.first(); hwdevice; hwdevice = cardReaderList.next()) {
+ TDECryptographicCardDevice* cdevice = static_cast<TDECryptographicCardDevice*>(hwdevice);
+ connect(cdevice, TQT_SIGNAL(certificateListAvailable(TDECryptographicCardDevice*)), this, TQT_SLOT(cryptographicCardInserted(TDECryptographicCardDevice*)));
+ connect(cdevice, TQT_SIGNAL(cardRemoved(TDECryptographicCardDevice*)), this, TQT_SLOT(cryptographicCardRemoved(TDECryptographicCardDevice*)));
+ cdevice->enableCardMonitoring(true);
+ }
+
mControlPipeHandlerThread = new TQEventLoopThread();
mControlPipeHandler = new ControlPipeHandlerObject();
mControlPipeHandler->mKGreeterParent = this;
@@ -829,6 +847,60 @@ KGreeter::verifySetUser( const TQString &user )
slotUserEntered();
}
+void KGreeter::cryptographicCardInserted(TDECryptographicCardDevice* cdevice) {
+ TQString login_name = TQString::null;
+ X509CertificatePtrList certList = cdevice->cardX509Certificates();
+ if (certList.count() > 0) {
+ KSSLCertificate* card_cert = NULL;
+ card_cert = KSSLCertificate::fromX509(certList[0]);
+ TQStringList cert_subject_parts = TQStringList::split("/", card_cert->getSubject(), false);
+ for (TQStringList::Iterator it = cert_subject_parts.begin(); it != cert_subject_parts.end(); ++it ) {
+ TQString lcpart = (*it).lower();
+ if (lcpart.startsWith("cn=")) {
+ login_name = lcpart.right(lcpart.length() - strlen("cn="));
+ }
+ }
+ delete card_cert;
+ }
+
+ if (login_name != "") {
+ DM dm;
+ SessList sess;
+ bool vt_active = false;
+ bool user_active = false;
+ if (dm.localSessions(sess)) {
+ TQString user, loc;
+ for (SessList::ConstIterator it = sess.begin(); it != sess.end(); ++it) {
+ DM::sess2Str2(*it, user, loc);
+ if (user.startsWith(login_name + ": ")) {
+ // Found active session
+ user_active = true;
+ }
+ if ((*it).self) {
+ if ((*it).vt == dm.activeVT()) {
+ vt_active = true;
+ }
+ }
+ }
+ }
+
+ if (!user_active && vt_active) {
+ // Select the correct user
+ verify->setUser(login_name);
+ verifySetUser(login_name);
+ verify->lockUserEntry(true);
+
+ // Initiate login
+ verify->accept();
+ }
+ }
+}
+
+void KGreeter::cryptographicCardRemoved(TDECryptographicCardDevice* cdevice) {
+ verify->lockUserEntry(false);
+ verify->requestAbort();
+}
+
KStdGreeter::KStdGreeter()
: KGreeter()
, clock( 0 )
diff --git a/tdm/kfrontend/kgreeter.h b/tdm/kfrontend/kgreeter.h
index 7d1c1bc6..fa24622d 100644
--- a/tdm/kfrontend/kgreeter.h
+++ b/tdm/kfrontend/kgreeter.h
@@ -46,6 +46,8 @@ class TQListViewItem;
class KGreeter;
class SAKDlg;
+class TDECryptographicCardDevice;
+
struct SessType {
TQString name, type;
bool hid;
@@ -138,6 +140,8 @@ class KGreeter : public KGDialog, public KGVerifyHandler {
private slots:
void slotLoadPrevWM();
+ void cryptographicCardInserted(TDECryptographicCardDevice*);
+ void cryptographicCardRemoved(TDECryptographicCardDevice*);
private:
ControlPipeHandlerObject* mControlPipeHandler;
diff --git a/tdm/kfrontend/kgverify.cpp b/tdm/kfrontend/kgverify.cpp
index 46b89e9c..a02cc1c3 100644
--- a/tdm/kfrontend/kgverify.cpp
+++ b/tdm/kfrontend/kgverify.cpp
@@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "themer/tdmthemer.h"
#include "themer/tdmitem.h"
+#include "themer/tdmlabel.h"
#include <tdeapplication.h>
#include <tdelocale.h>
@@ -66,30 +67,31 @@ void KGVerifyHandler::updateStatus( bool, bool, int )
{
}
-KGVerify::KGVerify( KGVerifyHandler *_handler, KdmThemer *_themer,
- TQWidget *_parent, TQWidget *_predecessor,
- const TQString &_fixedUser,
- const PluginList &_pluginList,
- KGreeterPlugin::Function _func,
- KGreeterPlugin::Context _ctx )
+KGVerify::KGVerify(KGVerifyHandler *_handler, KdmThemer *_themer,
+ TQWidget *_parent, TQWidget *_predecessor,
+ const TQString &_fixedUser,
+ const PluginList &_pluginList,
+ KGreeterPlugin::Function _func,
+ KGreeterPlugin::Context _ctx)
: inherited()
- , coreLock( 0 )
- , fixedEntity( _fixedUser )
- , pluginList( _pluginList )
- , handler( _handler )
- , themer( _themer )
- , parent( _parent )
- , predecessor( _predecessor )
- , plugMenu( 0 )
- , curPlugin( -1 )
- , timedLeft( 0 )
- , func( _func )
- , ctx( _ctx )
- , enabled( true )
- , running( false )
- , suspended( false )
- , failed( false )
- , isClear( true )
+ , coreLock(0)
+ , fixedEntity(_fixedUser)
+ , pluginList(_pluginList)
+ , handler(_handler)
+ , themer(_themer)
+ , parent(_parent)
+ , predecessor(_predecessor)
+ , plugMenu(0)
+ , curPlugin(-1)
+ , timedLeft(0)
+ , func(_func)
+ , ctx(_ctx)
+ , enabled(true)
+ , running(false)
+ , suspended(false)
+ , failed(false)
+ , isClear(true)
+ , abortRequested(false)
{
connect( &timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimeout()) );
connect( kapp, TQT_SIGNAL(activity()), TQT_SLOT(slotActivity()) );
@@ -269,6 +271,14 @@ KGVerify::setUser( const TQString &user )
}
void
+KGVerify::lockUserEntry(const bool lock)
+{
+ // assert( fixedEntity.isEmpty() );
+ Debug( "%s->lockUserEntry(%\"s)\n", pName.data(), lock );
+ greet->lockUserEntry(lock);
+}
+
+void
KGVerify::setPassword( const TQString &pass )
{
greet->setPassword( pass );
@@ -374,6 +384,12 @@ KGVerify::reject()
doReject( true );
}
+void // not a slot - called manually by greeter
+KGVerify::requestAbort()
+{
+ abortRequested = true;
+}
+
void
KGVerify::setEnabled( bool on )
{
@@ -478,27 +494,28 @@ KGVerify::VErrBox( TQWidget *parent, const TQString &user, const char *msg )
}
void // private static
-KGVerify::VInfoBox( TQWidget *parent, const TQString &user, const char *msg )
+KGVerify::VInfoBox(TQWidget *parent, const TQString &user, const char *msg)
{
TQString mesg = TQString::fromLocal8Bit( msg );
TQRegExp rx( "^Warning: your account will expire in (\\d+) day" );
- if (rx.search( mesg ) >= 0) {
- int expire = rx.cap( 1 ).toInt();
+ if (rx.search(mesg) >= 0) {
+ int expire = rx.cap(1).toInt();
mesg = expire ?
i18n("Your account expires tomorrow.",
"Your account expires in %n days.", expire) :
i18n("Your account expires today.");
- } else {
+ }
+ else {
rx.setPattern( "^Warning: your password will expire in (\\d+) day" );
- if (rx.search( mesg ) >= 0) {
- int expire = rx.cap( 1 ).toInt();
+ if (rx.search(mesg) >= 0) {
+ int expire = rx.cap(1).toInt();
mesg = expire ?
i18n("Your password expires tomorrow.",
"Your password expires in %n days.", expire) :
i18n("Your password expires today.");
}
}
- VMsgBox( parent, user, infobox, mesg );
+ VMsgBox(parent, user, infobox, mesg);
}
bool // public static
@@ -597,9 +614,24 @@ KGVerify::handleVerify()
Debug( " echo = %d\n", echo );
ndelay = GRecvInt();
Debug( " ndelay = %d\n%s->textPrompt(...)\n", ndelay, pName.data() );
- greet->textPrompt( msg, echo, ndelay );
- if (msg)
- free( msg );
+ if (abortRequested) {
+ greet->textPrompt("", echo, ndelay);
+ abortRequested = false;
+ }
+ else {
+ if (msg && (msg[0] != 0)) {
+ // Reset password entry and change text
+ setPassPromptText(msg);
+ greet->start();
+ greet->textPrompt(msg, echo, ndelay);
+ }
+ else {
+ greet->textPrompt(msg, echo, ndelay);
+ }
+ }
+ if (msg) {
+ free(msg);
+ }
return;
case V_GET_BINARY:
Debug( " V_GET_BINARY\n" );
@@ -607,9 +639,16 @@ KGVerify::handleVerify()
Debug( " %d bytes prompt\n", ret );
ndelay = GRecvInt();
Debug( " ndelay = %d\n%s->binaryPrompt(...)\n", ndelay, pName.data() );
- greet->binaryPrompt( msg, ndelay );
- if (msg)
- free( msg );
+ if (abortRequested) {
+ gplugReturnBinary(NULL);
+ abortRequested = false;
+ }
+ else {
+ greet->binaryPrompt( msg, ndelay );
+ }
+ if (msg) {
+ free(msg);
+ }
return;
}
@@ -622,11 +661,12 @@ KGVerify::handleVerify()
curUser = user = TQString::fromLocal8Bit( msg );
// greet needs this to be able to return something useful from
// getEntity(). but the backend is still unable to tell a domain ...
- Debug( " %s->setUser(%\"s)\n", pName.data(), user.latin1() );
+ Debug(" %s->setUser(%\"s)\n", pName.data(), user.latin1());
greet->setUser( curUser );
- handler->verifySetUser( curUser );
- if (msg)
- free( msg );
+ handler->verifySetUser(curUser);
+ if (msg) {
+ free(msg);
+ }
continue;
case V_PRE_OK: // this is only for func == AuthChAuthTok
Debug( " V_PRE_OK\n" );
@@ -636,8 +676,9 @@ KGVerify::handleVerify()
// is not implemented yet.
authTok = true;
cont = true;
- Debug( "%s->succeeded()\n", pName.data() );
+ Debug("%s->succeeded()\n", pName.data());
greet->succeeded();
+ abortRequested = false;
continue;
case V_CHTOK_AUTH:
Debug( " V_CHTOK_AUTH\n" );
@@ -648,14 +689,16 @@ KGVerify::handleVerify()
Debug( " V_CHTOK\n" );
nfunc = KGreeterPlugin::ChAuthTok;
user = TQString::null;
- dchtok:
+ dchtok:
{
timer.stop();
Debug( "%s->succeeded()\n", pName.data() );
greet->succeeded();
+ abortRequested = false;
KGChTok chtok( parent, user, pluginList, curPlugin, nfunc, KGreeterPlugin::Login );
- if (!chtok.exec())
+ if (!chtok.exec()) {
goto retry;
+ }
handler->verifyOk();
return;
}
@@ -665,11 +708,16 @@ KGVerify::handleVerify()
Debug( " %s->textMessage(%\"s, true)\n", pName.data(), msg );
if (!greet->textMessage( msg, true )) {
Debug( " message passed\n" );
- VErrBox( parent, user, msg );
- } else
+ if (!abortRequested) {
+ VErrBox( parent, user, msg );
+ }
+ }
+ else {
Debug( " message swallowed\n" );
- if (msg)
- free( msg );
+ }
+ if (msg) {
+ free(msg);
+ }
continue;
case V_MSG_INFO:
Debug( " V_MSG_INFO\n" );
@@ -677,10 +725,14 @@ KGVerify::handleVerify()
Debug( " %s->textMessage(%\"s, false)\n", pName.data(), msg );
if (!greet->textMessage( msg, false )) {
Debug( " message passed\n" );
- VInfoBox( parent, user, msg );
- } else
- Debug( " message swallowed\n" );
- free( msg );
+ if (!abortRequested) {
+ VInfoBox(parent, user, msg);
+ }
+ }
+ else {
+ Debug(" message swallowed\n");
+ }
+ free(msg);
continue;
}
@@ -698,6 +750,7 @@ KGVerify::handleVerify()
if (ent != fixedEntity) {
Debug( "%s->failed()\n", pName.data() );
greet->failed();
+ abortRequested = false;
MsgBox( sorrybox,
i18n("Authenticated user (%1) does not match requested user (%2).\n")
.arg( ent ).arg( fixedEntity ) );
@@ -706,12 +759,17 @@ KGVerify::handleVerify()
}
Debug( "%s->succeeded()\n", pName.data() );
greet->succeeded();
+ abortRequested = false;
handler->verifyOk();
return;
}
Debug( "%s->failed()\n", pName.data() );
greet->failed();
+ abortRequested = false;
+
+ // Reset password prompt text
+ setPassPromptText(TQString::null, true);
if (ret == V_AUTH) {
Debug( " V_AUTH\n" );
@@ -736,17 +794,36 @@ KGVerify::handleVerify()
}
}
+void KGVerify::setPassPromptText(TQString text, bool use_default_text) {
+ if (themer) {
+ KdmItem* password_label = themer->findNode("password-label");
+ if (password_label) {
+ KdmLabel* pass_label = static_cast<KdmLabel*>(password_label);
+ if (use_default_text) {
+ pass_label->setText(pass_label->lookupStock("password-label"));
+ }
+ else {
+ pass_label->setText(text);
+ }
+ pass_label->update();
+ themer->updateGeometry(true);
+ static_cast<TQWidget *>(themer->parent())->repaint(true);
+ }
+ }
+}
+
void
KGVerify::gplugReturnText( const char *text, int tag )
{
- Debug( "%s: gplugReturnText(%\"s, %d)\n", pName.data(),
- tag & V_IS_SECRET ? "<masked>" : text, tag );
- GSendStr( text );
+ Debug("%s: gplugReturnText(%\"s, %d)\n", pName.data(), tag & V_IS_SECRET ? "<masked>" : text, tag);
+ GSendStr(text);
if (text) {
- GSendInt( tag );
+ GSendInt(tag);
handleVerify();
- } else
+ }
+ else {
coreLock = 0;
+ }
}
void
@@ -755,12 +832,13 @@ KGVerify::gplugReturnBinary( const char *data )
if (data) {
unsigned const char *up = (unsigned const char *)data;
int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24);
- Debug( "%s: gplugReturnBinary(%d bytes)\n", pName.data(), len );
- GSendArr( len, data );
+ Debug("%s: gplugReturnBinary(%d bytes)\n", pName.data(), len);
+ GSendArr(len, data);
handleVerify();
- } else {
- Debug( "%s: gplugReturnBinary(NULL)\n", pName.data() );
- GSendArr( 0, 0 );
+ }
+ else {
+ Debug("%s: gplugReturnBinary(NULL)\n", pName.data());
+ GSendArr(0, 0);
coreLock = 0;
}
}
diff --git a/tdm/kfrontend/kgverify.h b/tdm/kfrontend/kgverify.h
index 44fab973..7db52f2a 100644
--- a/tdm/kfrontend/kgverify.h
+++ b/tdm/kfrontend/kgverify.h
@@ -100,6 +100,7 @@ class KGVerify : public TQObject, public KGreeterPluginHandler {
void presetEntity( const TQString &entity, int field );
TQString getEntity() const;
void setUser( const TQString &user );
+ void lockUserEntry( const bool lock );
void setPassword( const TQString &pass );
/* virtual */ void selectPlugin( int id );
bool entitiesLocal() const;
@@ -113,6 +114,7 @@ class KGVerify : public TQObject, public KGreeterPluginHandler {
void resume();
void accept();
void reject();
+ void requestAbort();
int coreLock;
@@ -146,6 +148,7 @@ class KGVerify : public TQObject, public KGreeterPluginHandler {
bool capsLocked;
bool enabled, running, suspended, failed, delayed, cont;
bool authTok, isClear, timeable;
+ bool abortRequested;
static void VMsgBox( TQWidget *parent, const TQString &user, TQMessageBox::Icon type, const TQString &mesg );
static void VErrBox( TQWidget *parent, const TQString &user, const char *msg );
@@ -158,6 +161,7 @@ class KGVerify : public TQObject, public KGreeterPluginHandler {
void performAutoLogin();
bool scheduleAutoLogin( bool initial );
void doReject( bool initial );
+ void setPassPromptText(TQString text, bool use_default_text=false);
private slots:
//virtual void slotPluginSelected( int id ) = 0;
diff --git a/tdm/kfrontend/themer/tdmitem.cpp b/tdm/kfrontend/themer/tdmitem.cpp
index f5eabdb5..26a4887c 100644
--- a/tdm/kfrontend/themer/tdmitem.cpp
+++ b/tdm/kfrontend/themer/tdmitem.cpp
@@ -204,6 +204,22 @@ KdmItem::findNode( const TQString &_id ) const
return 0;
}
+KdmItem *
+KdmItem::findNodeByType( const TQString &_type ) const
+{
+ if (itemType == _type)
+ return const_cast<KdmItem *>( this );
+
+ TQValueList<KdmItem *>::ConstIterator it;
+ for (it = m_children.begin(); it != m_children.end(); ++it) {
+ KdmItem *t = (*it)->findNodeByType( _type );
+ if (t)
+ return t;
+ }
+
+ return 0;
+}
+
void
KdmItem::setWidget( TQWidget *widget )
{
@@ -336,11 +352,6 @@ KdmItem::paint( TQPainter *p, const TQRect &rect )
else {
// We have compositing support!
TQRgb blend_color = tqRgba(m_backgroundModifier, m_backgroundModifier, m_backgroundModifier, 0); // RGBA overlay
- float alpha = tqAlpha(blend_color) / 255.;
- int pixel = tqAlpha(blend_color) << 24 |
- int(tqRed(blend_color) * alpha) << 16 |
- int(tqGreen(blend_color) * alpha) << 8 |
- int(tqBlue(blend_color) * alpha);
TQImage img( myWidget->size(), 32 );
img = img.convertDepth(32);
diff --git a/tdm/kfrontend/themer/tdmitem.h b/tdm/kfrontend/themer/tdmitem.h
index be7fa65d..d2aeed69 100644
--- a/tdm/kfrontend/themer/tdmitem.h
+++ b/tdm/kfrontend/themer/tdmitem.h
@@ -152,6 +152,7 @@ public:
}
KdmItem *findNode( const TQString &id ) const;
+ KdmItem *findNodeByType( const TQString &type ) const;
virtual void setWidget( TQWidget *widget );
TQWidget *widget() const { return myWidget; }
virtual void setLayoutItem( TQLayoutItem *item );
diff --git a/tdm/kfrontend/themer/tdmlabel.h b/tdm/kfrontend/themer/tdmlabel.h
index 8b955fca..e45d6809 100644
--- a/tdm/kfrontend/themer/tdmlabel.h
+++ b/tdm/kfrontend/themer/tdmlabel.h
@@ -40,6 +40,9 @@ public:
KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name = 0 );
void setText( const TQString &txt );
+ /* Method to lookup the caption associated with an item */
+ TQString lookupStock( const TQString &stock );
+
protected:
// reimplemented; returns the minimum size of rendered text
virtual TQSize sizeHint();
@@ -71,9 +74,6 @@ public slots:
void slotAccel();
private:
- /* Method to lookup the caption associated with an item */
- TQString lookupStock( const TQString &stock );
-
/* Lookup variables in the text */
TQString lookupText( const TQString &t );
diff --git a/tdm/kfrontend/themer/tdmthemer.cpp b/tdm/kfrontend/themer/tdmthemer.cpp
index d6d051cf..6c27b762 100644
--- a/tdm/kfrontend/themer/tdmthemer.cpp
+++ b/tdm/kfrontend/themer/tdmthemer.cpp
@@ -117,6 +117,12 @@ KdmThemer::findNode( const TQString &item ) const
return rootItem->findNode( item );
}
+KdmItem *
+KdmThemer::findNodeByType( const TQString &item ) const
+{
+ return rootItem->findNodeByType( item );
+}
+
void
KdmThemer::updateGeometry( bool force )
{
diff --git a/tdm/kfrontend/themer/tdmthemer.h b/tdm/kfrontend/themer/tdmthemer.h
index 2b8865b4..785a116d 100644
--- a/tdm/kfrontend/themer/tdmthemer.h
+++ b/tdm/kfrontend/themer/tdmthemer.h
@@ -72,6 +72,7 @@ public:
virtual // just to put the reference in the vmt
KdmItem *findNode( const TQString & ) const;
+ KdmItem *findNodeByType( const TQString & ) const;
void updateGeometry( bool force ); // force = true for external calls
diff --git a/tdm/kfrontend/themes/circles/circles.xml b/tdm/kfrontend/themes/circles/circles.xml
index 0596e0ee..102cae7b 100644
--- a/tdm/kfrontend/themes/circles/circles.xml
+++ b/tdm/kfrontend/themes/circles/circles.xml
@@ -165,13 +165,13 @@
<normal color="#FF8080" alpha="0.0"/>
<pos anchor="w" y="50%" width="box" height="box"/>
<box orientation="vertical" xpadding="0" ypadding="0" spacing="14">
- <item type="label">
+ <item type="label" id="username-label">
<pos anchor="ne" x="100%"/>
<normal color="#000000" font="Sans 12"/>
<!-- Stock label for: Username: -->
<stock type="username-label"/>
</item>
- <item type="label">
+ <item type="label" id="password-label">
<pos anchor="ne" x="100%"/>
<normal color="#000000" font="Sans 12"/>
<!-- Stock label for: Password: -->
diff --git a/tdm/kfrontend/themes/minimalist/minimalist.xml b/tdm/kfrontend/themes/minimalist/minimalist.xml
index f1dfada8..dd903679 100644
--- a/tdm/kfrontend/themes/minimalist/minimalist.xml
+++ b/tdm/kfrontend/themes/minimalist/minimalist.xml
@@ -37,7 +37,7 @@
</item>
<!-- user field -->
- <item type="label">
+ <item type="label" id="username-label">
<pos anchor="nw" x="145" y="225"/>
<normal font="Sans 11" color="#dfdbd2"/>
<stock type="username-label"/>
@@ -58,7 +58,7 @@
<!-- password field -->
- <item type="label">
+ <item type="label" id="password-label">
<pos anchor="nw" x="145" y="285"/>
<normal font="Sans 11" color="#dfdbd2"/>
<stock type="password-label"/>
diff --git a/tdm/kfrontend/themes/o2_enterprise/enterprise.xml b/tdm/kfrontend/themes/o2_enterprise/enterprise.xml
index 39f159b0..11b87ae0 100644
--- a/tdm/kfrontend/themes/o2_enterprise/enterprise.xml
+++ b/tdm/kfrontend/themes/o2_enterprise/enterprise.xml
@@ -54,12 +54,12 @@
<normal alpha="0.0" color="#000000" />
<pos width="box" y="50%" anchor="w" height="box" />
<box xpadding="10" spacing="10" ypadding="0" orientation="vertical" >
- <item type="label" >
+ <item type="label" id="username-label">
<pos x="100%" anchor="ne" />
<normal color="#000000" font="Sans Condensed 10" />
<stock type="username-label" />
</item>
- <item type="label" >
+ <item type="label" id="password-label">
<pos x="100%" anchor="ne" />
<normal color="#000000" font="Sans Condensed 10" />
<stock type="password-label" />