diff options
Diffstat (limited to 'tdm/kfrontend/kgreeter.cpp')
-rw-r--r-- | tdm/kfrontend/kgreeter.cpp | 152 |
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 |