summaryrefslogtreecommitdiffstats
path: root/tdm/kfrontend/kgreeter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdm/kfrontend/kgreeter.cpp')
-rw-r--r--tdm/kfrontend/kgreeter.cpp152
1 files changed, 143 insertions, 9 deletions
diff --git a/tdm/kfrontend/kgreeter.cpp b/tdm/kfrontend/kgreeter.cpp
index aa89fd78e..5da8bfc51 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>
@@ -92,6 +99,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <X11/Xlib.h>
+#ifdef HAVE_KRB5
+#include <tde/libtdeldap.h>
+#endif
+
#define FIFO_DIR "/tmp/tdesocket-global/tdm"
#define FIFO_FILE "/tmp/tdesocket-global/tdm/tdmctl-%1"
#define FIFO_SAK_FILE "/tmp/tdesocket-global/tdm/tdmctl-sak-%1"
@@ -185,6 +196,7 @@ KGreeter::KGreeter( bool framed )
, prevValid( true )
, needLoad( false )
, themed( framed )
+ , showInfoMessages( true )
, closingDown( false )
{
stsFile = new KSimpleConfig( _stsFile );
@@ -234,6 +246,21 @@ KGreeter::~KGreeter()
delete stsFile;
}
+void KGreeter::cryptographicCardWatcherSetup() {
+ cardLoginUser = TQString::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);
+ }
+}
+
void KGreeter::done(int r) {
closingDown = true;
inherited::done(r);
@@ -414,9 +441,9 @@ class KCStringList : public TQValueList<TQCString> {
}
};
-class UserList {
+class KGreeterUserList {
public:
- UserList( char **in );
+ KGreeterUserList( char **in );
bool hasUser( const char *str ) const { return users.contains( str ); }
bool hasGroup( gid_t gid ) const
{ return groups.find( gid ) != groups.end(); }
@@ -427,7 +454,7 @@ class UserList {
TQValueList<gid_t> groups;
};
-UserList::UserList( char **in )
+KGreeterUserList::KGreeterUserList( char **in )
{
struct group *grp;
@@ -462,7 +489,7 @@ KGreeter::insertUsers(int limit_users)
default_pix.convertDepth( 32 ).smoothScale( ns, TQ_ScaleMin );
}
if (_showUsers == SHOW_ALL) {
- UserList noUsers( _noUsers );
+ KGreeterUserList noUsers( _noUsers );
TQDict<int> dupes( 1000 ); // Potential crash risk with buffer overrun?
TQStringList toinsert;
int count = 0;
@@ -528,7 +555,7 @@ KGreeter::insertUsers(int limit_users)
insertUser( default_pix, *it, ps );
}
} else {
- UserList users( _users );
+ KGreeterUserList users( _users );
if (users.hasGroups()) {
TQDict<int> dupes( 1000 );
for (setpwent(); (ps = getpwent()) != 0;) {
@@ -612,12 +639,13 @@ KGreeter::slotUserEntered()
{
if (userView) {
TQListViewItem *item;
- for (item = userView->firstChild(); item; item = item->nextSibling())
+ for (item = userView->firstChild(); item; item = item->nextSibling()) {
if (((UserListViewItem *)item)->login == curUser) {
userView->setSelected( item, true );
userView->ensureItemVisible( item );
goto oke;
}
+ }
userView->clearSelection();
}
oke:
@@ -735,15 +763,18 @@ KGreeter::slotLoadPrevWM()
}
}
- for (uint i = 0; i < sessionTypes.count() && !sessionTypes[i].hid; i++)
+ for (uint i = 0; i < sessionTypes.count() && !sessionTypes[i].hid; i++) {
if (sessionTypes[i].type == sess) {
free( sess );
setPrevWM( i );
+ curWMSession = sessionTypes[i].type.utf8();
return;
}
- if (curSel == -1)
+ }
+ if (curSel == -1) {
MsgBox( sorrybox, i18n("Your saved session type '%1' is not valid any more.\n"
"Please select a new one, otherwise 'default' will be used.").arg( sess ) );
+ }
free( sess );
prevValid = false;
}
@@ -829,6 +860,98 @@ KGreeter::verifySetUser( const TQString &user )
slotUserEntered();
}
+void KGreeter::cryptographicCardInserted(TDECryptographicCardDevice* cdevice) {
+#ifdef HAVE_KRB5
+ // Make sure card logins are enabled before attempting one
+ if (!LDAPManager::pkcsLoginEnabled()) {
+ return;
+ }
+#else
+ // Don't enable card-based logins if Kerberos integration was disabled
+ return;
+#endif
+
+ 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 != "") {
+ if (verify->cardLoginInProgress) {
+ return;
+ }
+ verify->cardLoginInProgress = true;
+ verify->cardLoginDevice = cdevice;
+
+ 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);
+ if (userView) {
+ userView->setEnabled(false);
+ }
+ verifySetUser(login_name);
+ verify->lockUserEntry(true);
+
+ // FIXME
+ // pam_pkcs11 is extremely chatty with no apparent way to disable the unwanted messages
+ verify->setInfoMessageDisplay(false);
+
+ // Set up password prompt
+ cardLoginUser = login_name;
+ verify->setPasswordPrompt(i18n("PIN:"));
+
+ // Bypass initial password prompt
+ verify->start();
+ verify->setPassword("");
+ verify->accept();
+ }
+ }
+}
+
+void KGreeter::cryptographicCardRemoved(TDECryptographicCardDevice* cdevice) {
+ cardLoginUser = TQString::null;
+ userView->setEnabled(false);
+ verify->lockUserEntry(false);
+ verify->requestAbort();
+ verify->setPasswordPrompt(TQString::null);
+
+ // Restore information message display settings
+ verify->setInfoMessageDisplay(showInfoMessages);
+
+ verify->cardLoginInProgress = false;
+ verify->cardLoginDevice = NULL;
+}
+
KStdGreeter::KStdGreeter()
: KGreeter()
, clock( 0 )
@@ -974,7 +1097,10 @@ KStdGreeter::KStdGreeter()
pluginSetup();
+ verify->setInfoMessageDisplay(showInfoMessages);
verify->start();
+
+ TQTimer::singleShot(0, this, SLOT(cryptographicCardWatcherSetup()));
}
void
@@ -1039,8 +1165,9 @@ KThemedGreeter::KThemedGreeter()
xauth_warning = themer->findNode( "xauth-warning" ); // tdm ext
pam_error = themer->findNode( "pam-error" );
timed_label = themer->findNode( "timed-label" );
- if (pam_error && pam_error->isA( "KdmLabel" ))
+ if (pam_error && pam_error->isA( "KdmLabel" )) {
static_cast<KdmLabel*>(pam_error)->setText( i18n("Login Failed.") );
+ }
KdmItem *itm;
if ((itm = themer->findNode( "pam-message" ))) // done via msgboxes
@@ -1121,7 +1248,10 @@ KThemedGreeter::KThemedGreeter()
pluginSetup();
+ verify->setInfoMessageDisplay(showInfoMessages);
verify->start();
+
+ TQTimer::singleShot(0, this, SLOT(cryptographicCardWatcherSetup()));
}
bool
@@ -1199,6 +1329,10 @@ KThemedGreeter::updateStatus( bool fail, bool caps, int timedleft )
timed_label->hide( true );
}
}
+
+ if (cardLoginUser != TQString::null) {
+ verify->setPasswordPrompt(i18n("PIN:"));
+ }
}
void