Add initial cryptographic card login support

Tested with themed greeter and SAK disabled
pull/2/head
Timothy Pearson 9 years ago
parent 5d20ad97bf
commit ce47730301

@ -72,8 +72,20 @@ PAM_conv (int num_msg, pam_message_type **msg,
repl[count].resp = pd->conv(ConvGetNormal, msg[count]->msg); repl[count].resp = pd->conv(ConvGetNormal, msg[count]->msg);
break; break;
case PAM_PROMPT_ECHO_OFF: case PAM_PROMPT_ECHO_OFF:
repl[count].resp = if (pd->classic) {
pd->conv(ConvGetHidden, pd->classic ? 0 : msg[count]->msg); // 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")) {
repl[count].resp = pd->conv(ConvGetHidden, msg[count]->msg);
}
else {
repl[count].resp = pd->conv(ConvGetHidden, 0);
}
}
else {
repl[count].resp = pd->conv(ConvGetHidden, msg[count]->msg);
}
break; break;
#ifdef PAM_BINARY_PROMPT #ifdef PAM_BINARY_PROMPT
case PAM_BINARY_PROMPT: case PAM_BINARY_PROMPT:

@ -779,8 +779,8 @@ void DevicePropertiesDialog::populateDeviceInformation() {
if (m_device->type() == TDEGenericDeviceType::CryptographicCard) { if (m_device->type() == TDEGenericDeviceType::CryptographicCard) {
TDECryptographicCardDevice* cdevice = static_cast<TDECryptographicCardDevice*>(m_device); TDECryptographicCardDevice* cdevice = static_cast<TDECryptographicCardDevice*>(m_device);
connect(cdevice, TQT_SIGNAL(cardInserted()), this, TQT_SLOT(cryptographicCardInserted())); connect(cdevice, TQT_SIGNAL(cardInserted(TDECryptographicCardDevice*)), this, TQT_SLOT(cryptographicCardInserted()));
connect(cdevice, TQT_SIGNAL(cardRemoved()), this, TQT_SLOT(cryptographicCardRemoved())); connect(cdevice, TQT_SIGNAL(cardRemoved(TDECryptographicCardDevice*)), this, TQT_SLOT(cryptographicCardRemoved()));
updateCryptographicCardStatusDisplay(); updateCryptographicCardStatusDisplay();
} }
@ -926,6 +926,7 @@ void DevicePropertiesDialog::cryptLUKSAddKey() {
unsigned int key_slot = lvi->text(0).toUInt(); unsigned int key_slot = lvi->text(0).toUInt();
bool allow_card = false; bool allow_card = false;
bool use_card = false; bool use_card = false;
bool luks_card_key_modified = false;
KSSLCertificate* card_cert = NULL; KSSLCertificate* card_cert = NULL;
X509* card_cert_x509; X509* card_cert_x509;
TQString disk_uuid = sdevice->diskUUID(); TQString disk_uuid = sdevice->diskUUID();
@ -988,6 +989,7 @@ void DevicePropertiesDialog::cryptLUKSAddKey() {
// Use the secret key as the LUKS passcode // Use the secret key as the LUKS passcode
new_password = randomKey; new_password = randomKey;
luks_card_key_modified = true;
} }
else { else {
KMessageBox::error(this, i18n("<qt><b>Key creation failed</b><br>Please check that you have write access to /etc/trinity/luks/card and try again</qt>"), i18n("Key creation failure")); KMessageBox::error(this, i18n("<qt><b>Key creation failed</b><br>Please check that you have write access to /etc/trinity/luks/card and try again</qt>"), i18n("Key creation failure"));
@ -1081,6 +1083,16 @@ void DevicePropertiesDialog::cryptLUKSAddKey() {
sdevice->cryptClearOperationsUnlockPassword(); sdevice->cryptClearOperationsUnlockPassword();
KMessageBox::error(this, i18n("<qt><b>Key write failed</b><br>Please check the LUKS password and try again</qt>"), i18n("Key write failure")); KMessageBox::error(this, i18n("<qt><b>Key write failed</b><br>Please check the LUKS password and try again</qt>"), i18n("Key write failure"));
} }
else {
if (luks_card_key_modified) {
if (KMessageBox::warningYesNo(this, i18n("<qt><b>You have created a new card-dependent key</b><br>Card-dependent keys work in conjunction with an encrypted key file stored on the host system.<br>When a card is used to boot, card-dependent keys must be updated in the initramfs image to become usable.<p>Would you like to update the initramfs image now?</qt>"), i18n("Update Required")) == KMessageBox::Yes) {
// Update the initramfs
if (system("update-initramfs -u -k all") != 0) {
KMessageBox::error(this, i18n("<qt><b>Initramfs update failed</b><br>Card-dependent keys may not be available for use until the root storage device is available / unlocked</qt>"), i18n("Initramfs update failure"));
}
}
}
}
} }
} }
} }

@ -513,7 +513,17 @@ void PasswordDlg::handleVerify()
case ConvGetHidden: case ConvGetHidden:
if (!GRecvArr( &arr )) if (!GRecvArr( &arr ))
break; break;
greet->textPrompt( arr, false, false ); if (arr && (arr[0] != 0)) {
// Reset password entry and change text
greet->start();
greet->textPrompt( arr, false, false );
// Force relayout
setFixedSize( sizeHint().width(), sizeHint().height() + 1 );
setFixedSize( sizeHint() );
}
else {
greet->textPrompt( arr, false, false );
}
if (arr) if (arr)
::free( arr ); ::free( arr );
return; return;
@ -915,4 +925,14 @@ void PasswordDlg::capsLocked()
updateLabel(); updateLabel();
} }
void PasswordDlg::attemptCardLogin() {
greet->start();
greet->next();
}
void PasswordDlg::resetCardLogin() {
greet->abort();
greet->start();
}
#include "lockdlg.moc" #include "lockdlg.moc"

@ -49,6 +49,9 @@ class PasswordDlg : public TQDialog, public KGreeterPluginHandler
virtual void gplugStart(); virtual void gplugStart();
virtual void gplugActivity(); virtual void gplugActivity();
virtual void gplugMsgBox( TQMessageBox::Icon type, const TQString &text ); virtual void gplugMsgBox( TQMessageBox::Icon type, const TQString &text );
virtual void attemptCardLogin();
virtual void resetCardLogin();
protected: protected:
virtual void timerEvent(TQTimerEvent *); virtual void timerEvent(TQTimerEvent *);

@ -34,6 +34,7 @@
#include <tdeapplication.h> #include <tdeapplication.h>
#include <kservicegroup.h> #include <kservicegroup.h>
#include <kdebug.h> #include <kdebug.h>
#include <kuser.h>
#include <tdemessagebox.h> #include <tdemessagebox.h>
#include <tdeglobalsettings.h> #include <tdeglobalsettings.h>
#include <tdelocale.h> #include <tdelocale.h>
@ -112,6 +113,8 @@ Status DPMSInfo ( Display *, CARD16 *, BOOL * );
#include <GL/glx.h> #include <GL/glx.h>
#endif #endif
#define KDESKTOP_DEBUG_ID 1204
#define LOCK_GRACE_DEFAULT 5000 #define LOCK_GRACE_DEFAULT 5000
#define AUTOLOGOUT_DEFAULT 600 #define AUTOLOGOUT_DEFAULT 600
@ -146,7 +149,7 @@ Atom kde_wm_transparent_to_black = 0;
static void segv_handler(int) static void segv_handler(int)
{ {
kdError(1204) << "A fatal exception was encountered." kdError(KDESKTOP_DEBUG_ID) << "A fatal exception was encountered."
<< " Trapping and ignoring it so as not to compromise desktop security..." << " Trapping and ignoring it so as not to compromise desktop security..."
<< kdBacktrace() << endl; << kdBacktrace() << endl;
sleep(1); sleep(1);
@ -272,7 +275,7 @@ LockProcess::LockProcess()
KServiceGroup::Ptr servGroup = KServiceGroup::baseGroup( "screensavers"); KServiceGroup::Ptr servGroup = KServiceGroup::baseGroup( "screensavers");
if (servGroup) { if (servGroup) {
relPath=servGroup->relPath(); relPath=servGroup->relPath();
kdDebug(1204) << "relPath=" << relPath << endl; kdDebug(KDESKTOP_DEBUG_ID) << "relPath=" << relPath << endl;
} }
TDEGlobal::dirs()->addResourceType("scrsav", TDEGlobal::dirs()->addResourceType("scrsav",
TDEGlobal::dirs()->kde_default("apps") + TDEGlobal::dirs()->kde_default("apps") +
@ -290,6 +293,19 @@ LockProcess::LockProcess()
} }
} }
// 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, SIGNAL(pinRequested(TQString,TDECryptographicCardDevice*)), this, SLOT(cryptographicCardPinRequested(TQString,TDECryptographicCardDevice*)));
connect(cdevice, TQT_SIGNAL(cardInserted(TDECryptographicCardDevice*)), this, TQT_SLOT(cryptographicCardInserted(TDECryptographicCardDevice*)));
connect(cdevice, TQT_SIGNAL(cardRemoved(TDECryptographicCardDevice*)), this, TQT_SLOT(cryptographicCardRemoved(TDECryptographicCardDevice*)));
cdevice->enableCardMonitoring(true);
// cdevice->enablePINEntryCallbacks(true);
}
#ifdef KEEP_MOUSE_UNGRABBED #ifdef KEEP_MOUSE_UNGRABBED
setEnabled(false); setEnabled(false);
#endif #endif
@ -781,11 +797,11 @@ void LockProcess::readSaver()
TQStringList saverTypes = TQStringList::split(";", saverType); TQStringList saverTypes = TQStringList::split(";", saverType);
for (uint i = 0; i < saverTypes.count(); i++) { for (uint i = 0; i < saverTypes.count(); i++) {
if ((saverTypes[i] == "ManipulateScreen") && !manipulatescreen) { if ((saverTypes[i] == "ManipulateScreen") && !manipulatescreen) {
kdDebug(1204) << "Screensaver is type ManipulateScreen and ManipulateScreen is forbidden" << endl; kdDebug(KDESKTOP_DEBUG_ID) << "Screensaver is type ManipulateScreen and ManipulateScreen is forbidden" << endl;
mForbidden = true; mForbidden = true;
} }
if ((saverTypes[i] == "OpenGL") && !opengl) { if ((saverTypes[i] == "OpenGL") && !opengl) {
kdDebug(1204) << "Screensaver is type OpenGL and OpenGL is forbidden" << endl; kdDebug(KDESKTOP_DEBUG_ID) << "Screensaver is type OpenGL and OpenGL is forbidden" << endl;
mForbidden = true; mForbidden = true;
} }
if (saverTypes[i] == "OpenGL") { if (saverTypes[i] == "OpenGL") {
@ -794,7 +810,7 @@ void LockProcess::readSaver()
} }
} }
kdDebug(1204) << "mForbidden: " << (mForbidden ? "true" : "false") << endl; kdDebug(KDESKTOP_DEBUG_ID) << "mForbidden: " << (mForbidden ? "true" : "false") << endl;
if (trinity_desktop_lock_use_system_modal_dialogs) { if (trinity_desktop_lock_use_system_modal_dialogs) {
if (config.hasActionGroup("InWindow")) { if (config.hasActionGroup("InWindow")) {
@ -968,7 +984,7 @@ void LockProcess::createSaverWindow()
} }
} }
kdDebug(1204) << "Saver window Id: " << winId() << endl; kdDebug(KDESKTOP_DEBUG_ID) << "Saver window Id: " << winId() << endl;
} }
void LockProcess::desktopResized() void LockProcess::desktopResized()
@ -1307,7 +1323,7 @@ bool LockProcess::startSaver(bool notify_ready)
{ {
if (!child_saver && !grabInput()) if (!child_saver && !grabInput())
{ {
kdWarning(1204) << "LockProcess::startSaver() grabInput() failed!!!!" << endl; kdWarning(KDESKTOP_DEBUG_ID) << "LockProcess::startSaver() grabInput() failed!!!!" << endl;
return false; return false;
} }
mBusy = false; mBusy = false;
@ -1393,7 +1409,7 @@ bool LockProcess::startSaver(bool notify_ready)
// //
void LockProcess::stopSaver() void LockProcess::stopSaver()
{ {
kdDebug(1204) << "LockProcess: stopping saver" << endl; kdDebug(KDESKTOP_DEBUG_ID) << "LockProcess: stopping saver" << endl;
mHackProc.kill(SIGCONT); mHackProc.kill(SIGCONT);
stopHack(); stopHack();
mSuspended = false; mSuspended = false;
@ -1446,30 +1462,30 @@ bool LockProcess::startLock()
GreeterPluginHandle plugin; GreeterPluginHandle plugin;
TQString path = KLibLoader::self()->findLibrary( ((*it)[0] == '/' ? *it : "kgreet_" + *it ).latin1() ); TQString path = KLibLoader::self()->findLibrary( ((*it)[0] == '/' ? *it : "kgreet_" + *it ).latin1() );
if (path.isEmpty()) { if (path.isEmpty()) {
kdWarning(1204) << "GreeterPlugin " << *it << " does not exist" << endl; kdWarning(KDESKTOP_DEBUG_ID) << "GreeterPlugin " << *it << " does not exist" << endl;
continue; continue;
} }
if (!(plugin.library = KLibLoader::self()->library( path.latin1() ))) { if (!(plugin.library = KLibLoader::self()->library( path.latin1() ))) {
kdWarning(1204) << "Cannot load GreeterPlugin " << *it << " (" << path << ")" << endl; kdWarning(KDESKTOP_DEBUG_ID) << "Cannot load GreeterPlugin " << *it << " (" << path << ")" << endl;
continue; continue;
} }
if (!plugin.library->hasSymbol( "kgreeterplugin_info" )) { if (!plugin.library->hasSymbol( "kgreeterplugin_info" )) {
kdWarning(1204) << "GreeterPlugin " << *it << " (" << path << ") is no valid greet widget plugin" << endl; kdWarning(KDESKTOP_DEBUG_ID) << "GreeterPlugin " << *it << " (" << path << ") is no valid greet widget plugin" << endl;
plugin.library->unload(); plugin.library->unload();
continue; continue;
} }
plugin.info = (kgreeterplugin_info*)plugin.library->symbol( "kgreeterplugin_info" ); plugin.info = (kgreeterplugin_info*)plugin.library->symbol( "kgreeterplugin_info" );
if (plugin.info->method && !mMethod.isEmpty() && mMethod != plugin.info->method) { if (plugin.info->method && !mMethod.isEmpty() && mMethod != plugin.info->method) {
kdDebug(1204) << "GreeterPlugin " << *it << " (" << path << ") serves " << plugin.info->method << ", not " << mMethod << endl; kdDebug(KDESKTOP_DEBUG_ID) << "GreeterPlugin " << *it << " (" << path << ") serves " << plugin.info->method << ", not " << mMethod << endl;
plugin.library->unload(); plugin.library->unload();
continue; continue;
} }
if (!plugin.info->init( mMethod, getConf, this )) { if (!plugin.info->init( mMethod, getConf, this )) {
kdDebug(1204) << "GreeterPlugin " << *it << " (" << path << ") refuses to serve " << mMethod << endl; kdDebug(KDESKTOP_DEBUG_ID) << "GreeterPlugin " << *it << " (" << path << ") refuses to serve " << mMethod << endl;
plugin.library->unload(); plugin.library->unload();
continue; continue;
} }
kdDebug(1204) << "GreeterPlugin " << *it << " (" << plugin.info->method << ", " << plugin.info->name << ") loaded" << endl; kdDebug(KDESKTOP_DEBUG_ID) << "GreeterPlugin " << *it << " (" << plugin.info->method << ", " << plugin.info->name << ") loaded" << endl;
greetPlugin = plugin; greetPlugin = plugin;
mLocked = true; mLocked = true;
DM().setLock( true ); DM().setLock( true );
@ -1588,7 +1604,7 @@ bool LockProcess::startHack()
if (!path.isEmpty()) { if (!path.isEmpty()) {
mHackProc << path; mHackProc << path;
kdDebug(1204) << "Starting hack: " << path << endl; kdDebug(KDESKTOP_DEBUG_ID) << "Starting hack: " << path << endl;
while (!ts.atEnd()) { while (!ts.atEnd()) {
ts >> word; ts >> word;
@ -2297,10 +2313,10 @@ void LockProcess::stayOnTop()
// and stack others below it // and stack others below it
Window* stack = new Window[ mDialogs.count() + mVkbdWindows.count() + 1 ]; Window* stack = new Window[ mDialogs.count() + mVkbdWindows.count() + 1 ];
int count = 0; int count = 0;
for( TQValueList< VkbdWindow >::ConstIterator it = mVkbdWindows.begin(); it != mVkbdWindows.end(); ++it ) for( TQValueList< VkbdWindow >::ConstIterator it = mVkbdWindows.begin(); it != mVkbdWindows.end(); ++it ) {
stack[ count++ ] = (*it).id; stack[ count++ ] = (*it).id;
} }
for( TQValueList< TQWidget* >::ConstIterator it = mDialogs.begin(); it != mDialogs.end(); ++it ) for( TQValueList< TQWidget* >::ConstIterator it = mDialogs.begin(); it != mDialogs.end(); ++it ) {
stack[ count++ ] = (*it)->winId(); stack[ count++ ] = (*it)->winId();
} }
stack[ count++ ] = winId(); stack[ count++ ] = winId();
@ -2795,6 +2811,110 @@ void LockProcess::processInputPipeCommand(TQString inputcommand) {
} }
} }
void LockProcess::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 != "") {
KUser user;
if (login_name == user.loginName()) {
// Activate appropriate VT
DM dm;
SessList sess;
if (dm.localSessions(sess)) {
TQString user, loc;
for (SessList::ConstIterator it = sess.begin(); it != sess.end(); ++it) {
DM::sess2Str2(*it, user, loc);
if ((*it).self) {
// Switch VTs
DM().switchVT((*it).vt);
break;
}
}
}
// Pass login to the PAM stack...
if (dynamic_cast<SAKDlg*>(currentDialog)) {
dynamic_cast<SAKDlg*>(currentDialog)->closeDialogForced();
TQTimer::singleShot(0, this, SLOT(signalPassDlgToAttemptCardLogin()));
}
else if (dynamic_cast<SecureDlg*>(currentDialog)) {
dynamic_cast<SecureDlg*>(currentDialog)->closeDialogForced();
TQTimer::singleShot(0, this, SLOT(signalPassDlgToAttemptCardLogin()));
}
else if (dynamic_cast<PasswordDlg*>(currentDialog)) {
signalPassDlgToAttemptCardLogin();
}
}
}
}
void LockProcess::cryptographicCardRemoved(TDECryptographicCardDevice* cdevice) {
PasswordDlg* passDlg = dynamic_cast<PasswordDlg*>(currentDialog);
if (passDlg) {
passDlg->resetCardLogin();
}
else {
TQTimer::singleShot(0, this, SLOT(signalPassDlgToAttemptCardAbort()));
}
}
void LockProcess::signalPassDlgToAttemptCardLogin() {
PasswordDlg* passDlg = dynamic_cast<PasswordDlg*>(currentDialog);
if (passDlg) {
passDlg->attemptCardLogin();
}
else {
if (currentDialog) {
// Try again later
TQTimer::singleShot(0, this, SLOT(signalPassDlgToAttemptCardLogin()));
}
}
}
void LockProcess::signalPassDlgToAttemptCardAbort() {
PasswordDlg* passDlg = dynamic_cast<PasswordDlg*>(currentDialog);
if (passDlg) {
passDlg->resetCardLogin();
}
else {
if (currentDialog) {
// Try again later
TQTimer::singleShot(0, this, SLOT(signalPassDlgToAttemptCardAbort()));
}
}
}
void LockProcess::cryptographicCardPinRequested(TQString prompt, TDECryptographicCardDevice* cdevice) {
TQCString password;
const char * pin_entry;
QueryDlg qryDlg(this);
qryDlg.updateLabel(prompt);
qryDlg.setUnlockIcon();
mForceReject = false;
execDialog(&qryDlg);
if (mForceReject == false) {
pin_entry = qryDlg.getEntry();
cdevice->setProvidedPin(pin_entry);
}
else {
cdevice->setProvidedPin(TQString::null);
}
}
void LockProcess::fullyOnline() { void LockProcess::fullyOnline() {
if (!mFullyOnlineSent) { if (!mFullyOnlineSent) {
if (kdesktop_pid > 0) { if (kdesktop_pid > 0) {

@ -10,6 +10,11 @@
#ifndef __LOCKENG_H__ #ifndef __LOCKENG_H__
#define __LOCKENG_H__ #define __LOCKENG_H__
#include <ksslcertificate.h>
#include <tdehardwaredevices.h>
#include <tdecryptographiccarddevice.h>
#include <kgreeterplugin.h> #include <kgreeterplugin.h>
#include <kprocess.h> #include <kprocess.h>
@ -134,6 +139,11 @@ class LockProcess : public TQWidget
void startSecureDialog(); void startSecureDialog();
void slotMouseActivity(XEvent *event); void slotMouseActivity(XEvent *event);
void processInputPipeCommand(TQString command); void processInputPipeCommand(TQString command);
void cryptographicCardInserted(TDECryptographicCardDevice*);
void cryptographicCardRemoved(TDECryptographicCardDevice*);
void cryptographicCardPinRequested(TQString prompt, TDECryptographicCardDevice* cdevice);
void signalPassDlgToAttemptCardLogin();
void signalPassDlgToAttemptCardAbort();
private: private:
void configure(); void configure();

@ -372,15 +372,23 @@ int main( int argc, char **argv )
KSimpleConfig* tdmconfig; KSimpleConfig* tdmconfig;
OPEN_TDMCONFIG_AND_SET_GROUP OPEN_TDMCONFIG_AND_SET_GROUP
sigset_t new_mask;
sigset_t orig_mask;
// Block reception of all signals in this thread
sigprocmask(SIG_BLOCK, &new_mask, NULL);
// Create new LockProcess, which also spawns threads inheriting the blocked signal mask
trinity_desktop_lock_process = new LockProcess; trinity_desktop_lock_process = new LockProcess;
// Unblock reception of all signals in this thread
sigprocmask(SIG_UNBLOCK, &new_mask, NULL);
// Start loading core functions, such as the desktop wallpaper interface // Start loading core functions, such as the desktop wallpaper interface
app->processEvents(); app->processEvents();
if (args->isSet( "internal" )) { if (args->isSet( "internal" )) {
kdesktop_pid = atoi(args->getOption( "internal" )); kdesktop_pid = atoi(args->getOption( "internal" ));
sigset_t new_mask;
sigset_t orig_mask;
struct sigaction act; struct sigaction act;
in_internal_mode = TRUE; in_internal_mode = TRUE;

@ -11,10 +11,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <ksslcertificate.h>
#include <tdehardwaredevices.h>
#include <tdecryptographiccarddevice.h>
#include <kstandarddirs.h> #include <kstandarddirs.h>
#include <tdeapplication.h> #include <tdeapplication.h>
#include <kservicegroup.h> #include <kservicegroup.h>
#include <kdebug.h> #include <kdebug.h>
#include <kuser.h>
#include <tdelocale.h> #include <tdelocale.h>
#include <tqfile.h> #include <tqfile.h>
#include <tqtimer.h> #include <tqtimer.h>
@ -82,6 +88,7 @@ SaverEngine::SaverEngine()
mTerminationRequested(false), mTerminationRequested(false),
mSaverProcessReady(false), mSaverProcessReady(false),
mNewVTAfterLockEngage(false), mNewVTAfterLockEngage(false),
mValidCryptoCardInserted(false),
mSwitchVTAfterLockEngage(-1), mSwitchVTAfterLockEngage(-1),
dBusLocal(0), dBusLocal(0),
dBusWatch(0), dBusWatch(0),
@ -158,6 +165,17 @@ SaverEngine::SaverEngine()
sigaddset(&mThreadBlockSet, SIGTTIN); sigaddset(&mThreadBlockSet, SIGTTIN);
pthread_sigmask(SIG_BLOCK, &mThreadBlockSet, NULL); pthread_sigmask(SIG_BLOCK, &mThreadBlockSet, NULL);
// 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);
}
dBusConnect(); dBusConnect();
} }
@ -186,6 +204,43 @@ SaverEngine::~SaverEngine()
delete m_helperThread; delete m_helperThread;
} }
void SaverEngine::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 != "") {
KUser user;
if (login_name == user.loginName()) {
mValidCryptoCardInserted = true;
// Disable saver
enable(false);
}
}
}
void SaverEngine::cryptographicCardRemoved(TDECryptographicCardDevice* cdevice) {
if (mValidCryptoCardInserted) {
// Restore saver timeout
configure();
// Force lock
lockScreen();
}
mValidCryptoCardInserted = false;
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// This should be called only using DCOP. // This should be called only using DCOP.
@ -283,28 +338,25 @@ bool SaverEngine::enable( bool e )
mEnabled = e; mEnabled = e;
if (mEnabled) if (mEnabled) {
{
if ( !mXAutoLock ) { if ( !mXAutoLock ) {
mXAutoLock = new XAutoLock(); mXAutoLock = new XAutoLock();
connect(mXAutoLock, TQT_SIGNAL(timeout()), TQT_SLOT(idleTimeout())); connect(mXAutoLock, TQT_SIGNAL(timeout()), TQT_SLOT(idleTimeout()));
} }
mXAutoLock->setTimeout(mTimeout); mXAutoLock->setTimeout(mTimeout);
mXAutoLock->setDPMS(true); mXAutoLock->setDPMS(true);
//mXAutoLock->changeCornerLockStatus( mLockCornerTopLeft, mLockCornerTopRight, mLockCornerBottomLeft, mLockCornerBottomRight); //mXAutoLock->changeCornerLockStatus( mLockCornerTopLeft, mLockCornerTopRight, mLockCornerBottomLeft, mLockCornerBottomRight);
// We'll handle blanking // We'll handle blanking
XSetScreenSaver(tqt_xdisplay(), mTimeout + 10, mXInterval, PreferBlanking, mXExposures); XSetScreenSaver(tqt_xdisplay(), mTimeout + 10, mXInterval, PreferBlanking, mXExposures);
kdDebug() << "XSetScreenSaver " << mTimeout + 10 << endl; kdDebug() << "XSetScreenSaver " << mTimeout + 10 << endl;
mXAutoLock->start(); mXAutoLock->start();
kdDebug(1204) << "Saver Engine started, timeout: " << mTimeout << endl; kdDebug(1204) << "Saver Engine started, timeout: " << mTimeout << endl;
} }
else else {
{ if (mXAutoLock) {
if (mXAutoLock)
{
delete mXAutoLock; delete mXAutoLock;
mXAutoLock = 0; mXAutoLock = 0;
} }

@ -18,6 +18,7 @@
#include <tqdbusconnection.h> #include <tqdbusconnection.h>
class TDECryptographicCardDevice;
class DCOPClientTransaction; class DCOPClientTransaction;
class TQT_DBusMessage; class TQT_DBusMessage;
class TQT_DBusProxy; class TQT_DBusProxy;
@ -134,6 +135,9 @@ private slots:
void handleSecureDialog(); void handleSecureDialog();
void slotSAKProcessExited(); void slotSAKProcessExited();
void cryptographicCardInserted(TDECryptographicCardDevice*);
void cryptographicCardRemoved(TDECryptographicCardDevice*);
/** /**
* Enable wallpaper exports * Enable wallpaper exports
*/ */
@ -186,6 +190,7 @@ private:
bool mTerminationRequested; bool mTerminationRequested;
bool mSaverProcessReady; bool mSaverProcessReady;
bool mNewVTAfterLockEngage; bool mNewVTAfterLockEngage;
bool mValidCryptoCardInserted;
int mSwitchVTAfterLockEngage; int mSwitchVTAfterLockEngage;
struct sigaction mSignalAction; struct sigaction mSignalAction;
TQT_DBusConnection dBusConn; TQT_DBusConnection dBusConn;

@ -21,3 +21,4 @@ include( ConfigureChecks.cmake )
add_subdirectory( backend ) add_subdirectory( backend )
add_subdirectory( kfrontend ) add_subdirectory( kfrontend )
add_subdirectory( cryptocardwatcher )

@ -180,7 +180,7 @@ PAM_conv( int num_msg,
ReInitErrorLog(); ReInitErrorLog();
Debug( "PAM_conv\n" ); Debug( "PAM_conv\n" );
for (count = 0; count < num_msg; count++) for (count = 0; count < num_msg; count++) {
switch (msg[count]->msg_style) { switch (msg[count]->msg_style) {
case PAM_TEXT_INFO: case PAM_TEXT_INFO:
Debug( " PAM_TEXT_INFO: %s\n", msg[count]->msg ); 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_ON: cannot happen */
case PAM_PROMPT_ECHO_OFF: case PAM_PROMPT_ECHO_OFF:
Debug( " PAM_PROMPT_ECHO_OFF (usecur): %s\n", msg[count]->msg ); Debug( " PAM_PROMPT_ECHO_OFF (usecur): %s\n", msg[count]->msg );
if (!curpass) // WARNING
pd->gconv( GCONV_PASS, 0 ); // This is far from foolproof, but it's the best we can do at this time...
StrDup( &reply[count].resp, curpass ); // 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; break;
default: default:
LogError( "Unknown PAM message style <%d>\n", msg[count]->msg_style ); 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 */ reply[count].resp_retcode = PAM_SUCCESS; /* unused in linux-pam */
} }
}
Debug( " PAM_conv success\n" ); Debug( " PAM_conv success\n" );
*resp = reply; *resp = reply;
return PAM_SUCCESS; return PAM_SUCCESS;
@ -769,7 +779,6 @@ Verify( GConvFunc gconv, int rootok )
} }
#ifdef USE_PAM #ifdef USE_PAM
Debug( " pam_acct_mgmt() ...\n" ); Debug( " pam_acct_mgmt() ...\n" );
pretc = pam_acct_mgmt( pamh, 0 ); pretc = pam_acct_mgmt( pamh, 0 );
ReInitErrorLog(); ReInitErrorLog();

@ -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
)

@ -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;
}

@ -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"

@ -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__

@ -68,7 +68,7 @@ tde_add_executable( tdm_greet AUTOMOC
kfdialog.cpp kgdialog.cpp kchooser.cpp kgverify.cpp kfdialog.cpp kgdialog.cpp kchooser.cpp kgverify.cpp
tdmshutdown.cpp tdmadmindialog.cpp kgreeter.cpp tdmshutdown.cpp tdmadmindialog.cpp kgreeter.cpp
kgapp.cpp sakdlg.cc 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} DESTINATION ${BIN_INSTALL_DIR}
) )

@ -72,6 +72,7 @@ bool has_twin = false;
bool is_themed = false; bool is_themed = false;
bool trinity_desktop_lock_use_sak = TRUE; bool trinity_desktop_lock_use_sak = TRUE;
bool trinity_desktop_synchronize_keyboard_lights = TRUE; bool trinity_desktop_synchronize_keyboard_lights = TRUE;
bool trinity_desktop_watch_cryptographic_cards = TRUE;
TQPoint primaryScreenPosition; TQPoint primaryScreenPosition;
static int static int
@ -216,6 +217,7 @@ kg_main( const char *argv0 )
TDEProcess *tsak = 0; TDEProcess *tsak = 0;
TDEProcess *kbdl = 0; TDEProcess *kbdl = 0;
TDEProcess *ccsm = 0;
TDEProcess *proc = 0; TDEProcess *proc = 0;
TDEProcess *comp = 0; TDEProcess *comp = 0;
TDEProcess *dcop = 0; TDEProcess *dcop = 0;
@ -252,6 +254,12 @@ kg_main( const char *argv0 )
kbdl->start(); kbdl->start();
} }
if (trinity_desktop_watch_cryptographic_cards) {
ccsm = new TDEProcess;
*ccsm << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + "tdecryptocardwatcher";
ccsm->start();
}
XSetErrorHandler( ignoreXError ); XSetErrorHandler( ignoreXError );
argb_visual_available = false; argb_visual_available = false;
char *display = 0; char *display = 0;
@ -518,6 +526,10 @@ kg_main( const char *argv0 )
kbdl->closeStdin(); kbdl->closeStdin();
kbdl->detach(); kbdl->detach();
} }
if (ccsm) {
ccsm->closeStdin();
ccsm->detach();
}
if (comp) { if (comp) {
if (comp->isRunning()) { if (comp->isRunning()) {
if (_compositor == TDE_COMPOSITOR_BINARY) { if (_compositor == TDE_COMPOSITOR_BINARY) {

@ -33,6 +33,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "themer/tdmitem.h" #include "themer/tdmitem.h"
#include "themer/tdmlabel.h" #include "themer/tdmlabel.h"
#include <dmctl.h>
#include <ksslcertificate.h>
#include <tdehardwaredevices.h>
#include <tdecryptographiccarddevice.h>
#include <tdeapplication.h> #include <tdeapplication.h>
#include <tdelocale.h> #include <tdelocale.h>
#include <kstandarddirs.h> #include <kstandarddirs.h>
@ -212,6 +219,17 @@ KGreeter::KGreeter( bool framed )
pluginList = KGVerify::init( _pluginsLogin ); 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(); mControlPipeHandlerThread = new TQEventLoopThread();
mControlPipeHandler = new ControlPipeHandlerObject(); mControlPipeHandler = new ControlPipeHandlerObject();
mControlPipeHandler->mKGreeterParent = this; mControlPipeHandler->mKGreeterParent = this;
@ -829,6 +847,60 @@ KGreeter::verifySetUser( const TQString &user )
slotUserEntered(); 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() KStdGreeter::KStdGreeter()
: KGreeter() : KGreeter()
, clock( 0 ) , clock( 0 )

@ -46,6 +46,8 @@ class TQListViewItem;
class KGreeter; class KGreeter;
class SAKDlg; class SAKDlg;
class TDECryptographicCardDevice;
struct SessType { struct SessType {
TQString name, type; TQString name, type;
bool hid; bool hid;
@ -138,6 +140,8 @@ class KGreeter : public KGDialog, public KGVerifyHandler {
private slots: private slots:
void slotLoadPrevWM(); void slotLoadPrevWM();
void cryptographicCardInserted(TDECryptographicCardDevice*);
void cryptographicCardRemoved(TDECryptographicCardDevice*);
private: private:
ControlPipeHandlerObject* mControlPipeHandler; ControlPipeHandlerObject* mControlPipeHandler;

@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "themer/tdmthemer.h" #include "themer/tdmthemer.h"
#include "themer/tdmitem.h" #include "themer/tdmitem.h"
#include "themer/tdmlabel.h"
#include <tdeapplication.h> #include <tdeapplication.h>
#include <tdelocale.h> #include <tdelocale.h>
@ -66,30 +67,31 @@ void KGVerifyHandler::updateStatus( bool, bool, int )
{ {
} }
KGVerify::KGVerify( KGVerifyHandler *_handler, KdmThemer *_themer, KGVerify::KGVerify(KGVerifyHandler *_handler, KdmThemer *_themer,
TQWidget *_parent, TQWidget *_predecessor, TQWidget *_parent, TQWidget *_predecessor,
const TQString &_fixedUser, const TQString &_fixedUser,
const PluginList &_pluginList, const PluginList &_pluginList,
KGreeterPlugin::Function _func, KGreeterPlugin::Function _func,
KGreeterPlugin::Context _ctx ) KGreeterPlugin::Context _ctx)
: inherited() : inherited()
, coreLock( 0 ) , coreLock(0)
, fixedEntity( _fixedUser ) , fixedEntity(_fixedUser)
, pluginList( _pluginList ) , pluginList(_pluginList)
, handler( _handler ) , handler(_handler)
, themer( _themer ) , themer(_themer)
, parent( _parent ) , parent(_parent)
, predecessor( _predecessor ) , predecessor(_predecessor)
, plugMenu( 0 ) , plugMenu(0)
, curPlugin( -1 ) , curPlugin(-1)
, timedLeft( 0 ) , timedLeft(0)
, func( _func ) , func(_func)
, ctx( _ctx ) , ctx(_ctx)
, enabled( true ) , enabled(true)
, running( false ) , running(false)
, suspended( false ) , suspended(false)
, failed( false ) , failed(false)
, isClear( true ) , isClear(true)
, abortRequested(false)
{ {
connect( &timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimeout()) ); connect( &timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimeout()) );
connect( kapp, TQT_SIGNAL(activity()), TQT_SLOT(slotActivity()) ); connect( kapp, TQT_SIGNAL(activity()), TQT_SLOT(slotActivity()) );
@ -268,6 +270,14 @@ KGVerify::setUser( const TQString &user )
gplugActivity(); gplugActivity();
} }
void
KGVerify::lockUserEntry(const bool lock)
{
// assert( fixedEntity.isEmpty() );
Debug( "%s->lockUserEntry(%\"s)\n", pName.data(), lock );
greet->lockUserEntry(lock);
}
void void
KGVerify::setPassword( const TQString &pass ) KGVerify::setPassword( const TQString &pass )
{ {
@ -374,6 +384,12 @@ KGVerify::reject()
doReject( true ); doReject( true );
} }
void // not a slot - called manually by greeter
KGVerify::requestAbort()
{
abortRequested = true;
}
void void
KGVerify::setEnabled( bool on ) KGVerify::setEnabled( bool on )
{ {
@ -478,27 +494,28 @@ KGVerify::VErrBox( TQWidget *parent, const TQString &user, const char *msg )
} }
void // private static 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 ); TQString mesg = TQString::fromLocal8Bit( msg );
TQRegExp rx( "^Warning: your account will expire in (\\d+) day" ); TQRegExp rx( "^Warning: your account will expire in (\\d+) day" );
if (rx.search( mesg ) >= 0) { if (rx.search(mesg) >= 0) {
int expire = rx.cap( 1 ).toInt(); int expire = rx.cap(1).toInt();
mesg = expire ? mesg = expire ?
i18n("Your account expires tomorrow.", i18n("Your account expires tomorrow.",
"Your account expires in %n days.", expire) : "Your account expires in %n days.", expire) :
i18n("Your account expires today."); i18n("Your account expires today.");
} else { }
else {
rx.setPattern( "^Warning: your password will expire in (\\d+) day" ); rx.setPattern( "^Warning: your password will expire in (\\d+) day" );
if (rx.search( mesg ) >= 0) { if (rx.search(mesg) >= 0) {
int expire = rx.cap( 1 ).toInt(); int expire = rx.cap(1).toInt();
mesg = expire ? mesg = expire ?
i18n("Your password expires tomorrow.", i18n("Your password expires tomorrow.",
"Your password expires in %n days.", expire) : "Your password expires in %n days.", expire) :
i18n("Your password expires today."); i18n("Your password expires today.");
} }
} }
VMsgBox( parent, user, infobox, mesg ); VMsgBox(parent, user, infobox, mesg);
} }
bool // public static bool // public static
@ -597,9 +614,24 @@ KGVerify::handleVerify()
Debug( " echo = %d\n", echo ); Debug( " echo = %d\n", echo );
ndelay = GRecvInt(); ndelay = GRecvInt();
Debug( " ndelay = %d\n%s->textPrompt(...)\n", ndelay, pName.data() ); Debug( " ndelay = %d\n%s->textPrompt(...)\n", ndelay, pName.data() );
greet->textPrompt( msg, echo, ndelay ); if (abortRequested) {
if (msg) greet->textPrompt("", echo, ndelay);
free( msg ); 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; return;
case V_GET_BINARY: case V_GET_BINARY:
Debug( " V_GET_BINARY\n" ); Debug( " V_GET_BINARY\n" );
@ -607,9 +639,16 @@ KGVerify::handleVerify()
Debug( " %d bytes prompt\n", ret ); Debug( " %d bytes prompt\n", ret );
ndelay = GRecvInt(); ndelay = GRecvInt();
Debug( " ndelay = %d\n%s->binaryPrompt(...)\n", ndelay, pName.data() ); Debug( " ndelay = %d\n%s->binaryPrompt(...)\n", ndelay, pName.data() );
greet->binaryPrompt( msg, ndelay ); if (abortRequested) {
if (msg) gplugReturnBinary(NULL);
free( msg ); abortRequested = false;
}
else {
greet->binaryPrompt( msg, ndelay );
}
if (msg) {
free(msg);
}
return; return;
} }
@ -622,11 +661,12 @@ KGVerify::handleVerify()
curUser = user = TQString::fromLocal8Bit( msg ); curUser = user = TQString::fromLocal8Bit( msg );
// greet needs this to be able to return something useful from // greet needs this to be able to return something useful from
// getEntity(). but the backend is still unable to tell a domain ... // 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 ); greet->setUser( curUser );
handler->verifySetUser( curUser ); handler->verifySetUser(curUser);
if (msg) if (msg) {
free( msg ); free(msg);
}
continue; continue;
case V_PRE_OK: // this is only for func == AuthChAuthTok case V_PRE_OK: // this is only for func == AuthChAuthTok
Debug( " V_PRE_OK\n" ); Debug( " V_PRE_OK\n" );
@ -636,8 +676,9 @@ KGVerify::handleVerify()
// is not implemented yet. // is not implemented yet.
authTok = true; authTok = true;
cont = true; cont = true;
Debug( "%s->succeeded()\n", pName.data() ); Debug("%s->succeeded()\n", pName.data());
greet->succeeded(); greet->succeeded();
abortRequested = false;
continue; continue;
case V_CHTOK_AUTH: case V_CHTOK_AUTH:
Debug( " V_CHTOK_AUTH\n" ); Debug( " V_CHTOK_AUTH\n" );
@ -648,14 +689,16 @@ KGVerify::handleVerify()
Debug( " V_CHTOK\n" ); Debug( " V_CHTOK\n" );
nfunc = KGreeterPlugin::ChAuthTok; nfunc = KGreeterPlugin::ChAuthTok;
user = TQString::null; user = TQString::null;
dchtok: dchtok:
{ {
timer.stop(); timer.stop();
Debug( "%s->succeeded()\n", pName.data() ); Debug( "%s->succeeded()\n", pName.data() );
greet->succeeded(); greet->succeeded();
abortRequested = false;
KGChTok chtok( parent, user, pluginList, curPlugin, nfunc, KGreeterPlugin::Login ); KGChTok chtok( parent, user, pluginList, curPlugin, nfunc, KGreeterPlugin::Login );
if (!chtok.exec()) if (!chtok.exec()) {
goto retry; goto retry;
}
handler->verifyOk(); handler->verifyOk();
return; return;
} }
@ -665,11 +708,16 @@ KGVerify::handleVerify()
Debug( " %s->textMessage(%\"s, true)\n", pName.data(), msg ); Debug( " %s->textMessage(%\"s, true)\n", pName.data(), msg );
if (!greet->textMessage( msg, true )) { if (!greet->textMessage( msg, true )) {
Debug( " message passed\n" ); Debug( " message passed\n" );
VErrBox( parent, user, msg ); if (!abortRequested) {
} else VErrBox( parent, user, msg );
}
}
else {
Debug( " message swallowed\n" ); Debug( " message swallowed\n" );
if (msg) }
free( msg ); if (msg) {
free(msg);
}
continue; continue;
case V_MSG_INFO: case V_MSG_INFO:
Debug( " V_MSG_INFO\n" ); Debug( " V_MSG_INFO\n" );
@ -677,10 +725,14 @@ KGVerify::handleVerify()
Debug( " %s->textMessage(%\"s, false)\n", pName.data(), msg ); Debug( " %s->textMessage(%\"s, false)\n", pName.data(), msg );
if (!greet->textMessage( msg, false )) { if (!greet->textMessage( msg, false )) {
Debug( " message passed\n" ); Debug( " message passed\n" );
VInfoBox( parent, user, msg ); if (!abortRequested) {
} else VInfoBox(parent, user, msg);
Debug( " message swallowed\n" ); }
free( msg ); }
else {
Debug(" message swallowed\n");
}
free(msg);
continue; continue;
} }
@ -698,6 +750,7 @@ KGVerify::handleVerify()
if (ent != fixedEntity) { if (ent != fixedEntity) {
Debug( "%s->failed()\n", pName.data() ); Debug( "%s->failed()\n", pName.data() );
greet->failed(); greet->failed();
abortRequested = false;
MsgBox( sorrybox, MsgBox( sorrybox,
i18n("Authenticated user (%1) does not match requested user (%2).\n") i18n("Authenticated user (%1) does not match requested user (%2).\n")
.arg( ent ).arg( fixedEntity ) ); .arg( ent ).arg( fixedEntity ) );
@ -706,12 +759,17 @@ KGVerify::handleVerify()
} }
Debug( "%s->succeeded()\n", pName.data() ); Debug( "%s->succeeded()\n", pName.data() );
greet->succeeded(); greet->succeeded();
abortRequested = false;
handler->verifyOk(); handler->verifyOk();
return; return;
} }
Debug( "%s->failed()\n", pName.data() ); Debug( "%s->failed()\n", pName.data() );
greet->failed(); greet->failed();
abortRequested = false;
// Reset password prompt text
setPassPromptText(TQString::null, true);
if (ret == V_AUTH) { if (ret == V_AUTH) {
Debug( " V_AUTH\n" ); 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 void
KGVerify::gplugReturnText( const char *text, int tag ) KGVerify::gplugReturnText( const char *text, int tag )
{ {
Debug( "%s: gplugReturnText(%\"s, %d)\n", pName.data(), Debug("%s: gplugReturnText(%\"s, %d)\n", pName.data(), tag & V_IS_SECRET ? "<masked>" : text, tag);
tag & V_IS_SECRET ? "<masked>" : text, tag ); GSendStr(text);
GSendStr( text );
if (text) { if (text) {
GSendInt( tag ); GSendInt(tag);
handleVerify(); handleVerify();
} else }
else {
coreLock = 0; coreLock = 0;
}
} }
void void
@ -755,12 +832,13 @@ KGVerify::gplugReturnBinary( const char *data )
if (data) { if (data) {
unsigned const char *up = (unsigned const char *)data; unsigned const char *up = (unsigned const char *)data;
int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24); int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24);
Debug( "%s: gplugReturnBinary(%d bytes)\n", pName.data(), len ); Debug("%s: gplugReturnBinary(%d bytes)\n", pName.data(), len);
GSendArr( len, data ); GSendArr(len, data);
handleVerify(); handleVerify();
} else { }
Debug( "%s: gplugReturnBinary(NULL)\n", pName.data() ); else {
GSendArr( 0, 0 ); Debug("%s: gplugReturnBinary(NULL)\n", pName.data());
GSendArr(0, 0);
coreLock = 0; coreLock = 0;
} }
} }

@ -100,6 +100,7 @@ class KGVerify : public TQObject, public KGreeterPluginHandler {
void presetEntity( const TQString &entity, int field ); void presetEntity( const TQString &entity, int field );
TQString getEntity() const; TQString getEntity() const;
void setUser( const TQString &user ); void setUser( const TQString &user );
void lockUserEntry( const bool lock );
void setPassword( const TQString &pass ); void setPassword( const TQString &pass );
/* virtual */ void selectPlugin( int id ); /* virtual */ void selectPlugin( int id );
bool entitiesLocal() const; bool entitiesLocal() const;
@ -113,6 +114,7 @@ class KGVerify : public TQObject, public KGreeterPluginHandler {
void resume(); void resume();
void accept(); void accept();
void reject(); void reject();
void requestAbort();
int coreLock; int coreLock;
@ -146,6 +148,7 @@ class KGVerify : public TQObject, public KGreeterPluginHandler {
bool capsLocked; bool capsLocked;
bool enabled, running, suspended, failed, delayed, cont; bool enabled, running, suspended, failed, delayed, cont;
bool authTok, isClear, timeable; bool authTok, isClear, timeable;
bool abortRequested;
static void VMsgBox( TQWidget *parent, const TQString &user, TQMessageBox::Icon type, const TQString &mesg ); 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 ); static void VErrBox( TQWidget *parent, const TQString &user, const char *msg );
@ -158,6 +161,7 @@ class KGVerify : public TQObject, public KGreeterPluginHandler {
void performAutoLogin(); void performAutoLogin();
bool scheduleAutoLogin( bool initial ); bool scheduleAutoLogin( bool initial );
void doReject( bool initial ); void doReject( bool initial );
void setPassPromptText(TQString text, bool use_default_text=false);
private slots: private slots:
//virtual void slotPluginSelected( int id ) = 0; //virtual void slotPluginSelected( int id ) = 0;

@ -204,6 +204,22 @@ KdmItem::findNode( const TQString &_id ) const
return 0; 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 void
KdmItem::setWidget( TQWidget *widget ) KdmItem::setWidget( TQWidget *widget )
{ {
@ -336,11 +352,6 @@ KdmItem::paint( TQPainter *p, const TQRect &rect )
else { else {
// We have compositing support! // We have compositing support!
TQRgb blend_color = tqRgba(m_backgroundModifier, m_backgroundModifier, m_backgroundModifier, 0); // RGBA overlay 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 ); TQImage img( myWidget->size(), 32 );
img = img.convertDepth(32); img = img.convertDepth(32);

@ -152,6 +152,7 @@ public:
} }
KdmItem *findNode( const TQString &id ) const; KdmItem *findNode( const TQString &id ) const;
KdmItem *findNodeByType( const TQString &type ) const;
virtual void setWidget( TQWidget *widget ); virtual void setWidget( TQWidget *widget );
TQWidget *widget() const { return myWidget; } TQWidget *widget() const { return myWidget; }
virtual void setLayoutItem( TQLayoutItem *item ); virtual void setLayoutItem( TQLayoutItem *item );

@ -40,6 +40,9 @@ public:
KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name = 0 ); KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name = 0 );
void setText( const TQString &txt ); void setText( const TQString &txt );
/* Method to lookup the caption associated with an item */
TQString lookupStock( const TQString &stock );
protected: protected:
// reimplemented; returns the minimum size of rendered text // reimplemented; returns the minimum size of rendered text
virtual TQSize sizeHint(); virtual TQSize sizeHint();
@ -71,9 +74,6 @@ public slots:
void slotAccel(); void slotAccel();
private: private:
/* Method to lookup the caption associated with an item */
TQString lookupStock( const TQString &stock );
/* Lookup variables in the text */ /* Lookup variables in the text */
TQString lookupText( const TQString &t ); TQString lookupText( const TQString &t );

@ -117,6 +117,12 @@ KdmThemer::findNode( const TQString &item ) const
return rootItem->findNode( item ); return rootItem->findNode( item );
} }
KdmItem *
KdmThemer::findNodeByType( const TQString &item ) const
{
return rootItem->findNodeByType( item );
}
void void
KdmThemer::updateGeometry( bool force ) KdmThemer::updateGeometry( bool force )
{ {

@ -72,6 +72,7 @@ public:
virtual // just to put the reference in the vmt virtual // just to put the reference in the vmt
KdmItem *findNode( const TQString & ) const; KdmItem *findNode( const TQString & ) const;
KdmItem *findNodeByType( const TQString & ) const;
void updateGeometry( bool force ); // force = true for external calls void updateGeometry( bool force ); // force = true for external calls

@ -165,13 +165,13 @@
<normal color="#FF8080" alpha="0.0"/> <normal color="#FF8080" alpha="0.0"/>
<pos anchor="w" y="50%" width="box" height="box"/> <pos anchor="w" y="50%" width="box" height="box"/>
<box orientation="vertical" xpadding="0" ypadding="0" spacing="14"> <box orientation="vertical" xpadding="0" ypadding="0" spacing="14">
<item type="label"> <item type="label" id="username-label">
<pos anchor="ne" x="100%"/> <pos anchor="ne" x="100%"/>
<normal color="#000000" font="Sans 12"/> <normal color="#000000" font="Sans 12"/>
<!-- Stock label for: Username: --> <!-- Stock label for: Username: -->
<stock type="username-label"/> <stock type="username-label"/>
</item> </item>
<item type="label"> <item type="label" id="password-label">
<pos anchor="ne" x="100%"/> <pos anchor="ne" x="100%"/>
<normal color="#000000" font="Sans 12"/> <normal color="#000000" font="Sans 12"/>
<!-- Stock label for: Password: --> <!-- Stock label for: Password: -->

@ -37,7 +37,7 @@
</item> </item>
<!-- user field --> <!-- user field -->
<item type="label"> <item type="label" id="username-label">
<pos anchor="nw" x="145" y="225"/> <pos anchor="nw" x="145" y="225"/>
<normal font="Sans 11" color="#dfdbd2"/> <normal font="Sans 11" color="#dfdbd2"/>
<stock type="username-label"/> <stock type="username-label"/>
@ -58,7 +58,7 @@
<!-- password field --> <!-- password field -->
<item type="label"> <item type="label" id="password-label">
<pos anchor="nw" x="145" y="285"/> <pos anchor="nw" x="145" y="285"/>
<normal font="Sans 11" color="#dfdbd2"/> <normal font="Sans 11" color="#dfdbd2"/>
<stock type="password-label"/> <stock type="password-label"/>

@ -54,12 +54,12 @@
<normal alpha="0.0" color="#000000" /> <normal alpha="0.0" color="#000000" />
<pos width="box" y="50%" anchor="w" height="box" /> <pos width="box" y="50%" anchor="w" height="box" />
<box xpadding="10" spacing="10" ypadding="0" orientation="vertical" > <box xpadding="10" spacing="10" ypadding="0" orientation="vertical" >
<item type="label" > <item type="label" id="username-label">
<pos x="100%" anchor="ne" /> <pos x="100%" anchor="ne" />
<normal color="#000000" font="Sans Condensed 10" /> <normal color="#000000" font="Sans Condensed 10" />
<stock type="username-label" /> <stock type="username-label" />
</item> </item>
<item type="label" > <item type="label" id="password-label">
<pos x="100%" anchor="ne" /> <pos x="100%" anchor="ne" />
<normal color="#000000" font="Sans Condensed 10" /> <normal color="#000000" font="Sans Condensed 10" />
<stock type="password-label" /> <stock type="password-label" />

@ -25,6 +25,7 @@
#include <dcopclient.h> #include <dcopclient.h>
#include <tqregexp.h> #include <tqregexp.h>
#include <tqfile.h>
#include <X11/Xauth.h> #include <X11/Xauth.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -37,8 +38,34 @@
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <config.h>
static TQString readcfg(const char *cfg_file) {
TQString ctl = "/var/run/xdmctl";
TQStringList lines;
TQFile file(cfg_file);
if ( file.open( IO_ReadOnly ) ) {
TQTextStream stream(&file);
TQString line;
while ( !stream.atEnd() ) {
line = stream.readLine();
TQStringList keyvaluepair = TQStringList::split("=", line, false);
if (keyvaluepair.count() > 1) {
if (keyvaluepair[0].lower() == "FifoDir") {
ctl = keyvaluepair[1];
}
}
}
file.close();
}
return ctl;
}
static int DMType = DM::Unknown; static int DMType = DM::Unknown;
static const char *ctl, *dpy; static const char *dpy;
static TQString ctl;
DM::DM() : fd( -1 ) DM::DM() : fd( -1 )
{ {
@ -46,16 +73,27 @@ DM::DM() : fd( -1 )
struct sockaddr_un sa; struct sockaddr_un sa;
if (DMType == Unknown) { if (DMType == Unknown) {
if (!(dpy = ::getenv( "DISPLAY" ))) if (!(dpy = ::getenv( "DISPLAY" ))) {
DMType = NoDM; // Try to read TDM control file
else if ((ctl = ::getenv( "DM_CONTROL" ))) if ((ctl = readcfg(KDE_CONFDIR "/tdm/tdmrc")) != TQString::null) {
DMType = NewTDM;
}
else {
DMType = NoDM;
}
}
else if ((ctl = ::getenv( "DM_CONTROL" )) != TQString::null) {
DMType = NewTDM; DMType = NewTDM;
else if ((ctl = ::getenv( "XDM_MANAGED" )) && ctl[0] == '/') }
else if (((ctl = ::getenv( "XDM_MANAGED" )) != TQString::null) && ctl[0] == '/') {
DMType = OldTDM; DMType = OldTDM;
else if (::getenv( "GDMSESSION" )) }
else if (::getenv( "GDMSESSION" )) {
DMType = GDM; DMType = GDM;
else }
else {
DMType = NoDM; DMType = NoDM;
}
} }
switch (DMType) { switch (DMType) {
default: default:
@ -76,12 +114,17 @@ DM::DM() : fd( -1 )
} }
} }
GDMAuthenticate(); GDMAuthenticate();
} else { }
if ((ptr = const_cast<char*>(strchr( dpy, ':' )))) else {
ptr = strchr( ptr, '.' ); if (!dpy) {
snprintf( sa.sun_path, sizeof(sa.sun_path), snprintf( sa.sun_path, sizeof(sa.sun_path), "%s/dmctl/socket", ctl.ascii() );
"%s/dmctl-%.*s/socket", }
ctl, ptr ? int(ptr - dpy) : 512, dpy ); else {
if ((ptr = const_cast<char*>(strchr( dpy, ':' )))) {
ptr = strchr( ptr, '.' );
}
snprintf( sa.sun_path, sizeof(sa.sun_path), "%s/dmctl-%.*s/socket", ctl.ascii(), ptr ? int(ptr - dpy) : 512, dpy );
}
if (::connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) { if (::connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) {
::close( fd ); ::close( fd );
fd = -1; fd = -1;
@ -100,8 +143,9 @@ DM::DM() : fd( -1 )
DM::~DM() DM::~DM()
{ {
if (fd >= 0) if (fd >= 0) {
close( fd ); close( fd );
}
} }
bool bool
@ -172,13 +216,15 @@ DM::exec( const char *cmd, TQCString &buf )
bool bool
DM::canShutdown() DM::canShutdown()
{ {
if (DMType == OldTDM) if (DMType == OldTDM) {
return strstr( ctl, ",maysd" ) != 0; return strstr( ctl.ascii(), ",maysd" ) != 0;
}
TQCString re; TQCString re;
if (DMType == GDM) if (DMType == GDM) {
return exec( "QUERY_LOGOUT_ACTION\n", re ) && re.find("HALT") >= 0; return exec( "QUERY_LOGOUT_ACTION\n", re ) && re.find("HALT") >= 0;
}
return exec( "caps\n", re ) && re.find( "\tshutdown" ) >= 0; return exec( "caps\n", re ) && re.find( "\tshutdown" ) >= 0;
} }
@ -282,7 +328,7 @@ DM::numReserve()
return 1; /* Bleh */ return 1; /* Bleh */
if (DMType == OldTDM) if (DMType == OldTDM)
return strstr( ctl, ",rsvd" ) ? 1 : -1; return strstr( ctl.ascii(), ",rsvd" ) ? 1 : -1;
TQCString re; TQCString re;
int p; int p;
@ -304,8 +350,9 @@ DM::startReserve()
bool bool
DM::localSessions( SessList &list ) DM::localSessions( SessList &list )
{ {
if (DMType == OldTDM) if (DMType == OldTDM) {
return false; return false;
}
TQCString re; TQCString re;
@ -325,8 +372,9 @@ DM::localSessions( SessList &list )
list.append( se ); list.append( se );
} }
} else { } else {
if (!exec( "list\talllocal\n", re )) if (!exec( "list\talllocal\n", re )) {
return false; return false;
}
TQStringList sess = TQStringList::split( TQChar('\t'), re.data() + 3 ); TQStringList sess = TQStringList::split( TQChar('\t'), re.data() + 3 );
for (TQStringList::ConstIterator it = sess.begin(); it != sess.end(); ++it) { for (TQStringList::ConstIterator it = sess.begin(); it != sess.end(); ++it) {
TQStringList ts = TQStringList::split( TQChar(','), *it, true ); TQStringList ts = TQStringList::split( TQChar(','), *it, true );

@ -45,6 +45,15 @@ protected:
static int echoMode; static int echoMode;
TQString KClassicGreeter::passwordPrompt() {
if (func == Authenticate) {
return i18n("&Password:");
}
else {
return i18n("Current &password:");
}
}
KClassicGreeter::KClassicGreeter( KGreeterPluginHandler *_handler, KClassicGreeter::KClassicGreeter( KGreeterPluginHandler *_handler,
KdmThemer *themer, KdmThemer *themer,
TQWidget *parent, TQWidget *pred, TQWidget *parent, TQWidget *pred,
@ -60,7 +69,7 @@ KClassicGreeter::KClassicGreeter( KGreeterPluginHandler *_handler,
running( false ) running( false )
{ {
KdmItem *user_entry = 0, *pw_entry = 0; KdmItem *user_entry = 0, *pw_entry = 0;
TQGridLayout *grid = 0; grid = 0;
int line = 0; int line = 0;
layoutItem = 0; layoutItem = 0;
@ -120,11 +129,7 @@ KClassicGreeter::KClassicGreeter( KGreeterPluginHandler *_handler,
passwdEdit->adjustSize(); passwdEdit->adjustSize();
pw_entry->setWidget( passwdEdit ); pw_entry->setWidget( passwdEdit );
} else { } else {
passwdLabel = new TQLabel( passwdEdit, passwdLabel = new TQLabel( passwdEdit, passwordPrompt(), parent );
func == Authenticate ?
i18n("&Password:") :
i18n("Current &password:"),
parent );
grid->addWidget( passwdLabel, line, 0 ); grid->addWidget( passwdLabel, line, 0 );
grid->addWidget( passwdEdit, line++, 1 ); grid->addWidget( passwdEdit, line++, 1 );
} }
@ -217,6 +222,10 @@ KClassicGreeter::setUser( const TQString &user )
passwdEdit->selectAll(); passwdEdit->selectAll();
} }
void KClassicGreeter::lockUserEntry( const bool lock ) {
loginEdit->setEnabled(!lock);
}
void // virtual void // virtual
KClassicGreeter::setPassword( const TQString &pass ) KClassicGreeter::setPassword( const TQString &pass )
{ {
@ -276,10 +285,24 @@ void // virtual
KClassicGreeter::textPrompt( const char *prompt, bool echo, bool nonBlocking ) KClassicGreeter::textPrompt( const char *prompt, bool echo, bool nonBlocking )
{ {
pExp = exp; pExp = exp;
if (echo) if (echo) {
exp = 0; exp = 0;
else if (!authTok) }
else if (!authTok) {
exp = 1; exp = 1;
if (passwdLabel) {
if (prompt && (prompt[0] != 0)) {
passwdLabel->setText(prompt);
}
else {
passwdLabel->setText(passwordPrompt());
}
if (grid) {
grid->invalidate();
grid->activate();
}
}
}
else { else {
TQString pr( prompt ); TQString pr( prompt );
if (pr.find( TQRegExp( "\\bpassword\\b", false ) ) >= 0) { if (pr.find( TQRegExp( "\\bpassword\\b", false ) ) >= 0) {
@ -294,7 +317,8 @@ KClassicGreeter::textPrompt( const char *prompt, bool echo, bool nonBlocking )
KGreeterPluginHandler::IsSecret ); KGreeterPluginHandler::IsSecret );
return; return;
} }
} else { }
else {
handler->gplugMsgBox( TQMessageBox::Critical, handler->gplugMsgBox( TQMessageBox::Critical,
i18n("Unrecognized prompt \"%1\"") i18n("Unrecognized prompt \"%1\"")
.arg( prompt ) ); .arg( prompt ) );
@ -392,6 +416,15 @@ KClassicGreeter::succeeded()
void // virtual void // virtual
KClassicGreeter::failed() KClassicGreeter::failed()
{ {
if (passwdLabel) {
// reset password prompt
passwdLabel->setText(passwordPrompt());
if (grid) {
grid->invalidate();
grid->activate();
}
}
// assert( running || timed_login ); // assert( running || timed_login );
setActive( false ); setActive( false );
setActive2( false ); setActive2( false );
@ -402,6 +435,15 @@ KClassicGreeter::failed()
void // virtual void // virtual
KClassicGreeter::revive() KClassicGreeter::revive()
{ {
if (passwdLabel) {
// reset password prompt
passwdLabel->setText(passwordPrompt());
if (grid) {
grid->invalidate();
grid->activate();
}
}
// assert( !running ); // assert( !running );
setActive2( true ); setActive2( true );
if (authTok) { if (authTok) {
@ -425,6 +467,15 @@ KClassicGreeter::revive()
void // virtual void // virtual
KClassicGreeter::clear() KClassicGreeter::clear()
{ {
if (passwdLabel) {
// reset password prompt
passwdLabel->setText(passwordPrompt());
if (grid) {
grid->invalidate();
grid->activate();
}
}
// assert( !running && !passwd1Edit ); // assert( !running && !passwd1Edit );
passwdEdit->erase(); passwdEdit->erase();
if (loginEdit) { if (loginEdit) {

@ -50,6 +50,7 @@ class KClassicGreeter : public TQObject, public KGreeterPlugin {
virtual void presetEntity( const TQString &entity, int field ); virtual void presetEntity( const TQString &entity, int field );
virtual TQString getEntity() const; virtual TQString getEntity() const;
virtual void setUser( const TQString &user ); virtual void setUser( const TQString &user );
virtual void lockUserEntry( const bool lock );
virtual void setPassword( const TQString &pass ); virtual void setPassword( const TQString &pass );
virtual void setEnabled( bool on ); virtual void setEnabled( bool on );
virtual bool textMessage( const char *message, bool error ); virtual bool textMessage( const char *message, bool error );
@ -70,6 +71,7 @@ class KClassicGreeter : public TQObject, public KGreeterPlugin {
void slotActivity(); void slotActivity();
private: private:
TQString passwordPrompt();
void setActive( bool enable ); void setActive( bool enable );
void setActive2( bool enable ); void setActive2( bool enable );
void returnData(); void returnData();
@ -81,6 +83,7 @@ class KClassicGreeter : public TQObject, public KGreeterPlugin {
TQString fixedUser, curUser; TQString fixedUser, curUser;
Function func; Function func;
Context ctx; Context ctx;
TQGridLayout* grid;
int exp, pExp, has; int exp, pExp, has;
bool running, authTok; bool running, authTok;
}; };

@ -263,6 +263,10 @@ KPamGreeter::setUser( const TQString &user )
} }
} }
void KPamGreeter::lockUserEntry( const bool lock ) {
loginEdit->setEnabled(!lock);
}
void // virtual void // virtual
KPamGreeter::setPassword( const TQString &pass ) KPamGreeter::setPassword( const TQString &pass )
{ {

@ -50,6 +50,7 @@ class KPamGreeter : public TQObject, public KGreeterPlugin {
virtual void presetEntity( const TQString &entity, int field ); virtual void presetEntity( const TQString &entity, int field );
virtual TQString getEntity() const; virtual TQString getEntity() const;
virtual void setUser( const TQString &user ); virtual void setUser( const TQString &user );
virtual void lockUserEntry( const bool lock );
virtual void setPassword( const TQString &pass ); virtual void setPassword( const TQString &pass );
virtual void setEnabled( bool on ); virtual void setEnabled( bool on );
virtual bool textMessage( const char *message, bool error ); virtual bool textMessage( const char *message, bool error );

@ -297,6 +297,10 @@ KWinbindGreeter::setUser( const TQString &user )
passwdEdit->selectAll(); passwdEdit->selectAll();
} }
void KWinbindGreeter::lockUserEntry( const bool lock ) {
loginEdit->setEnabled(!lock);
}
void // virtual void // virtual
KWinbindGreeter::setPassword( const TQString &pass ) KWinbindGreeter::setPassword( const TQString &pass )
{ {

@ -54,6 +54,7 @@ class KWinbindGreeter : public TQObject, public KGreeterPlugin {
virtual void presetEntity( const TQString &entity, int field ); virtual void presetEntity( const TQString &entity, int field );
virtual TQString getEntity() const; virtual TQString getEntity() const;
virtual void setUser( const TQString &user ); virtual void setUser( const TQString &user );
virtual void lockUserEntry( const bool lock );
virtual void setPassword( const TQString &pass ); virtual void setPassword( const TQString &pass );
virtual void setEnabled( bool on ); virtual void setEnabled( bool on );
virtual bool textMessage( const char *message, bool error ); virtual bool textMessage( const char *message, bool error );

@ -151,6 +151,12 @@ public:
*/ */
virtual void setUser( const TQString &user ) = 0; virtual void setUser( const TQString &user ) = 0;
/**
* Lock or unlock editing of the username entry field
* @param lock true to lock, false to unlock
*/
virtual void lockUserEntry( const bool lock ) = 0;
/** /**
* "Push" a password into the talker. * "Push" a password into the talker.
* @param pass the password to set. * @param pass the password to set.
@ -183,7 +189,7 @@ public:
/** /**
* Prompt the user for data. Reply by calling handler->gplugReturnText(). * Prompt the user for data. Reply by calling handler->gplugReturnText().
* @param propmt the prompt to display. It may be null, in which case * @param prompt the prompt to display. It may be null, in which case
* "Username"/"Password" should be shown and the replies should be tagged * "Username"/"Password" should be shown and the replies should be tagged
* with the respective Is* flag. * with the respective Is* flag.
* @param echo if true, a normal input widget can be used, otherwise one that * @param echo if true, a normal input widget can be used, otherwise one that

Loading…
Cancel
Save