rpms/slim/F-7 slim-1.2.6-pam.patch,NONE,1.1 slim.spec,1.2,1.3
Anders F Björklund (afb)
fedora-extras-commits at redhat.com
Mon Sep 24 19:53:30 UTC 2007
Author: afb
Update of /cvs/pkgs/rpms/slim/F-7
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv10287
Modified Files:
slim.spec
Added Files:
slim-1.2.6-pam.patch
Log Message:
backport PAM support
slim-1.2.6-pam.patch:
--- NEW FILE slim-1.2.6-pam.patch ---
diff -uNbr --exclude=.svn release-1.2.6/Makefile slim-pam/Makefile
--- release-1.2.6/Makefile 2006-09-15 23:00:28.000000000 +0200
+++ slim-pam/Makefile 2007-06-05 12:57:54.000000000 +0200
@@ -8,6 +8,10 @@
CFLAGS=-I. -I/usr/X11R6/include -I/usr/include/freetype2 -I/usr/include/freetype2/config -I/usr/include/libpng12 -I/usr/include
LDFLAGS=-L/usr/X11R6/lib -lXft -lX11 -lfreetype -lXrender -lfontconfig -lpng12 -lz -lm -lcrypt -lXmu -lpng -ljpeg
CUSTOM=-DHAVE_SHADOW
+ifdef USE_PAM
+LDFLAGS+= -lpam
+CUSTOM+= -DUSE_PAM
+endif
PREFIX=/usr
CFGDIR=/etc
MANDIR=/usr/man
@@ -20,7 +24,10 @@
DEFINES=-DPACKAGE=\"$(NAME)\" -DVERSION=\"$(VERSION)\" \
-DPKGDATADIR=\"$(PREFIX)/share/slim\" -DSYSCONFDIR=\"$(CFGDIR)\"
-OBJECTS=jpeg.o png.o main.o image.o numlock.o cfg.o switchuser.o input.o app.o panel.o
+OBJECTS=jpeg.o png.o main.o image.o numlock.o cfg.o switchuser.o app.o panel.o
+ifdef USE_PAM
+OBJECTS+=PAM.o
+endif
all: slim
diff -uNbr --exclude=.svn release-1.2.6/Makefile.freebsd slim-pam/Makefile.freebsd
--- release-1.2.6/Makefile.freebsd 2006-09-15 23:00:28.000000000 +0200
+++ slim-pam/Makefile.freebsd 2007-06-11 13:00:09.000000000 +0200
@@ -8,6 +8,10 @@
CFLAGS=-I. -I/usr/X11R6/include -I/usr/local/include/freetype2 -I/usr/local/include/freetype2/config -I/usr/local/include/libpng -I/usr/local/include -I/usr/include
LDFLAGS=-L/usr/X11R6/lib -L/usr/local/lib -lXft -lX11 -lfreetype -lXrender -lfontconfig -lpng -lz -lm -lcrypt -lXmu -lpng -ljpeg
CUSTOM=-DNEEDS_BASENAME
+.ifdef(USE_PAM)
+ LDFLAGS+= -lpam
+ CUSTOM+= -DUSE_PAM
+.endif
PREFIX=/usr
CFGDIR=/etc
MANDIR=/usr/share/man
@@ -20,7 +24,10 @@
DEFINES=-DPACKAGE=\"$(NAME)\" -DVERSION=\"$(VERSION)\" \
-DPKGDATADIR=\"$(PREFIX)/share/slim\" -DSYSCONFDIR=\"$(CFGDIR)\"
-OBJECTS=jpeg.o png.o main.o image.o numlock.o cfg.o switchuser.o input.o app.o panel.o
+OBJECTS=jpeg.o png.o main.o image.o numlock.o cfg.o switchuser.o app.o panel.o
+.ifdef USE_PAM
+ OBJECTS+=PAM.o
+.endif
all: slim
diff -uNbr --exclude=.svn release-1.2.6/Makefile.netbsd slim-pam/Makefile.netbsd
--- release-1.2.6/Makefile.netbsd 2006-09-15 23:00:28.000000000 +0200
+++ slim-pam/Makefile.netbsd 2007-06-07 04:15:03.000000000 +0200
@@ -8,6 +8,10 @@
CFLAGS=-I. -I/usr/X11R6/include -I/usr/X11R6/include/freetype2 -I/usr/X11R6/include/freetype2/config -I/usr/pkg/include -I/usr/include
LDFLAGS=-L/usr/X11R6/lib -L/usr/pkg/lib -lXft -lX11 -lfreetype -lXrender -lfontconfig -lpng -lz -lm -lcrypt -lXmu -lpng -ljpeg
CUSTOM=-DNEEDS_BASENAME
+.ifdef(USE_PAM)
+ LDFLAGS+= -lpam
+ CUSTOM+= -DUSE_PAM
+.endif
PREFIX=/usr
CFGDIR=/etc
MANDIR=/usr/share/man
@@ -20,7 +24,10 @@
DEFINES=-DPACKAGE=\"$(NAME)\" -DVERSION=\"$(VERSION)\" \
-DPKGDATADIR=\"$(PREFIX)/share/slim\" -DSYSCONFDIR=\"$(CFGDIR)\"
-OBJECTS=jpeg.o png.o main.o image.o numlock.o cfg.o switchuser.o input.o app.o panel.o
+OBJECTS=jpeg.o png.o main.o image.o numlock.o cfg.o switchuser.o app.o panel.o
+.ifdef USE_PAM
+ OBJECTS+=PAM.o
+.endif
all: slim
diff -uNbr --exclude=.svn release-1.2.6/Makefile.openbsd slim-pam/Makefile.openbsd
--- release-1.2.6/Makefile.openbsd 2006-09-15 23:00:28.000000000 +0200
+++ slim-pam/Makefile.openbsd 2007-06-05 12:57:54.000000000 +0200
@@ -20,7 +20,7 @@
DEFINES=-DPACKAGE=\"$(NAME)\" -DVERSION=\"$(VERSION)\" \
-DPKGDATADIR=\"$(PREFIX)/share/slim\" -DSYSCONFDIR=\"$(CFGDIR)\"
-OBJECTS=jpeg.o png.o main.o image.o numlock.o cfg.o switchuser.o input.o app.o panel.o
+OBJECTS=jpeg.o png.o main.o image.o numlock.o cfg.o switchuser.o app.o panel.o
.SUFFIXES: .c.o .cpp.o
@@ -44,9 +44,6 @@
switchuser.o:
$(CXX) $(CFLAGS) $(DEFINES) $(CUSTOM) -c switchuser.cpp -o $@
-input.o:
- $(CXX) $(CFLAGS) $(DEFINES) $(CUSTOM) -c input.cpp -o $@
-
app.o:
$(CXX) $(CFLAGS) $(DEFINES) $(CUSTOM) -c app.cpp -o $@
diff -uNbr --exclude=.svn release-1.2.6/PAM.cpp slim-pam/PAM.cpp
--- release-1.2.6/PAM.cpp 1970-01-01 01:00:00.000000000 +0100
+++ slim-pam/PAM.cpp 2007-05-29 19:10:51.000000000 +0200
@@ -0,0 +1,275 @@
+/* SLiM - Simple Login Manager
+ Copyright (C) 2007 Martin Parm
+
+ This program 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 2 of the License, or
+ (at your option) any later version.
+*/
+#include <PAM.h>
+#include <string>
+#include <iostream>
+
+namespace PAM {
+ Exception::Exception(pam_handle_t* _pam_handle,
+ const std::string& _func_name,
+ int _errnum):
+ errnum(_errnum),
+ errstr(pam_strerror(_pam_handle, _errnum)),
+ func_name(_func_name)
+ {}
+
+ Exception::~Exception(void){}
+
+ Auth_Exception::Auth_Exception(pam_handle_t* _pam_handle,
+ const std::string& _func_name,
+ int _errnum):
+ Exception(_pam_handle, _func_name, _errnum){}
+
+ Cred_Exception::Cred_Exception(pam_handle_t* _pam_handle,
+ const std::string& _func_name,
+ int _errnum):
+ Exception(_pam_handle, _func_name, _errnum){}
+
+ int Authenticator::_end(void){
+ int result=pam_end(pam_handle, last_result);
+ pam_handle=0;
+ return result;
+ }
+
+ Authenticator::Authenticator(conversation* conv, void* data):
+ pam_handle(0),
+ last_result(PAM_SUCCESS)
+ {
+ pam_conversation.conv=conv;
+ pam_conversation.appdata_ptr=data;
+ }
+
+ Authenticator::~Authenticator(void){
+ if (pam_handle) _end();
+ }
+
+ void Authenticator::start(const std::string& service){
+ switch((last_result=pam_start(service.c_str(), NULL, &pam_conversation, &pam_handle))){
+ default:
+ throw Exception(pam_handle, "pam_start()", last_result);
+
+ case PAM_SUCCESS:
+ break;
+ }
+ return;
+ }
+
+ void Authenticator::end(void){
+ switch((last_result=_end())){
+ default:
+ throw Exception(pam_handle, "pam_end()", last_result);
+
+ case PAM_SUCCESS:
+ break;
+
+ }
+ return;
+ }
+
+ void Authenticator::set_item(const Authenticator::ItemType item, const void* value){
+ switch((last_result=pam_set_item(pam_handle, item, value))){
+ default:
+ _end();
+ throw Exception(pam_handle, "pam_set_item()", last_result);
+
+ case PAM_SUCCESS:
+ break;
+ }
+ return;
+ }
+
+ const void* Authenticator::get_item(const Authenticator::ItemType item){
+ const void* data;
+ switch ((last_result=pam_get_item(pam_handle, item, &data))){
+ default:
+ case PAM_SYSTEM_ERR:
+#ifdef __LIBPAM_VERSION
+ case PAM_BAD_ITEM:
+#endif
+ _end();
+ throw Exception(pam_handle, "pam_get_item()", last_result);
+
+ case PAM_PERM_DENIED: // The value of item was NULL
+ case PAM_SUCCESS:
+ break;
+ }
+ return data;
+ }
+
+#ifdef __LIBPAM_VERSION
+ void Authenticator::fail_delay(const unsigned int micro_sec){
+ switch((last_result=pam_fail_delay(pam_handle, micro_sec))){
+ default:
+ _end();
+ throw Exception(pam_handle, "fail_delay()", last_result);
+
+ case PAM_SUCCESS:
+ break;
+ }
+ return;
+ }
+#endif
+
+ void Authenticator::authenticate(void){
+ switch((last_result=pam_authenticate(pam_handle, 0))){
+ default:
+ case PAM_ABORT:
+ case PAM_AUTHINFO_UNAVAIL:
+ _end();
+ throw Exception(pam_handle, "pam_authenticate()", last_result);
+
+ case PAM_USER_UNKNOWN:
+ case PAM_MAXTRIES:
+ case PAM_CRED_INSUFFICIENT:
+ case PAM_AUTH_ERR:
+ throw Auth_Exception(pam_handle, "pam_authentication()", last_result);
+
+ case PAM_SUCCESS:
+ break;
+ }
+
+ switch((last_result=pam_acct_mgmt(pam_handle, PAM_SILENT))){
+ // The documentation and implementation of Linux PAM differs:
+ // PAM_NEW_AUTHTOKEN_REQD is described in the documentation but
+ // don't exists in the actual implementation. This issue needs
+ // to be fixes at some point.
+
+ default:
+ //case PAM_NEW_AUTHTOKEN_REQD:
+ case PAM_ACCT_EXPIRED:
+ case PAM_USER_UNKNOWN:
+ _end();
+ throw Exception(pam_handle, "pam_acct_mgmt()", last_result);
+
+ case PAM_AUTH_ERR:
+ case PAM_PERM_DENIED:
+ throw Auth_Exception(pam_handle, "pam_acct_mgmt()", last_result);
+
+ case PAM_SUCCESS:
+ break;
+ };
+ return;
+ }
+
+ void Authenticator::open_session(void){
+ switch((last_result=pam_setcred(pam_handle, PAM_ESTABLISH_CRED))){
+ default:
+ case PAM_CRED_ERR:
+ case PAM_CRED_UNAVAIL:
+ _end();
+ throw Exception(pam_handle, "pam_setcred()", last_result);
+
+ case PAM_CRED_EXPIRED:
+ case PAM_USER_UNKNOWN:
+ throw Cred_Exception(pam_handle, "pam_setcred()", last_result);
+
+ case PAM_SUCCESS:
+ break;
+ }
+
+ switch((last_result=pam_open_session(pam_handle, 0))){
+ // The documentation and implementation of Linux PAM differs:
+ // PAM_SESSION_ERROR is described in the documentation but
+ // don't exists in the actual implementation. This issue needs
+ // to be fixes at some point.
+
+ default:
+ //case PAM_SESSION_ERROR:
+ pam_setcred(pam_handle, PAM_DELETE_CRED);
+ _end();
+ throw Exception(pam_handle, "pam_open_session()", last_result);
+
+ case PAM_SUCCESS:
+ break;
+ };
+ return;
+ }
+
+ void Authenticator::close_session(void){
+ switch((last_result=pam_close_session(pam_handle, 0))){
+ // The documentation and implementation of Linux PAM differs:
+ // PAM_SESSION_ERROR is described in the documentation but
+ // don't exists in the actual implementation. This issue needs
+ // to be fixes at some point.
+
+ default:
+ //case PAM_SESSION_ERROR:
+ pam_setcred(pam_handle, PAM_DELETE_CRED);
+ _end();
+ throw Exception(pam_handle, "pam_close_session", last_result);
+
+ case PAM_SUCCESS:
+ break;
+ };
+ switch((last_result=pam_setcred(pam_handle, PAM_DELETE_CRED))){
+ default:
+ case PAM_CRED_ERR:
+ case PAM_CRED_UNAVAIL:
+ case PAM_CRED_EXPIRED:
+ case PAM_USER_UNKNOWN:
+ _end();
+ throw Exception(pam_handle, "pam_setcred()", last_result);
+
+ case PAM_SUCCESS:
+ break;
+ }
+ return;
+ }
+
+ void Authenticator::setenv(const std::string& key, const std::string& value){
+ std::string name_value = key+"="+value;
+ switch((last_result=pam_putenv(pam_handle, name_value.c_str()))){
+ default:
+ case PAM_PERM_DENIED:
+ case PAM_ABORT:
+ case PAM_BUF_ERR:
+#ifdef __LIBPAM_VERSION
+ case PAM_BAD_ITEM:
+#endif
+ _end();
+ throw Exception(pam_handle, "pam_putenv()", last_result);
+
+ case PAM_SUCCESS:
+ break;
+ };
+ return;
+ }
+
+ void Authenticator::delenv(const std::string& key){
+ switch((last_result=pam_putenv(pam_handle, key.c_str()))){
+ default:
+ case PAM_PERM_DENIED:
+ case PAM_ABORT:
+ case PAM_BUF_ERR:
+#ifdef __LIBPAM_VERSION
+ case PAM_BAD_ITEM:
+#endif
+ _end();
+ throw Exception(pam_handle, "pam_putenv()", last_result);
+
+ case PAM_SUCCESS:
+ break;
+ };
+ return;
+ }
+
+ const char* Authenticator::getenv(const std::string& key){
+ return pam_getenv(pam_handle, key.c_str());
+ }
+
+ char** Authenticator::getenvlist(void){
+ return pam_getenvlist(pam_handle);
+ }
+
+};
+
+std::ostream& operator<<( std::ostream& os, const PAM::Exception& e){
+ os << e.func_name << ": " << e.errstr;
+ return os;
+}
diff -uNbr --exclude=.svn release-1.2.6/PAM.h slim-pam/PAM.h
--- release-1.2.6/PAM.h 1970-01-01 01:00:00.000000000 +0100
+++ slim-pam/PAM.h 2007-06-07 04:16:01.000000000 +0200
@@ -0,0 +1,99 @@
+/* SLiM - Simple Login Manager
+ Copyright (C) 2007 Martin Parm
+
+ This program 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 2 of the License, or
+ (at your option) any later version.
+*/
+
+#ifndef _PAM_H_
+#define _PAM_H_
+#include <string>
+#include <security/pam_appl.h>
+
+#ifdef __LIBPAM_VERSION
+#include <security/pam_misc.h>
+#endif
+
+namespace PAM {
+ class Exception{
+ public:
+ int errnum;
+ std::string errstr;
+ std::string func_name;
+ Exception(pam_handle_t* _pam_handle,
+ const std::string& _func_name,
+ int _errnum);
+ virtual ~Exception(void);
+ };
+
+ class Auth_Exception: public Exception{
+ public:
+ Auth_Exception(pam_handle_t* _pam_handle,
+ const std::string& _func_name,
+ int _errnum);
+ };
+
+ class Cred_Exception: public Exception{
+ public:
+ Cred_Exception(pam_handle_t* _pam_handle,
+ const std::string& _func_name,
+ int _errnum);
+ };
+
+
+ class Authenticator{
+ private:
+ struct pam_conv pam_conversation;
+ pam_handle_t* pam_handle;
+ int last_result;
+
+ int _end(void);
+ public:
+ typedef int (conversation)(int num_msg,
+ const struct pam_message **msg,
+ struct pam_response **resp,
+ void *appdata_ptr);
+
+ enum ItemType {
+ Service = PAM_SERVICE,
+ User = PAM_USER,
+ User_Prompt = PAM_USER_PROMPT,
+ TTY = PAM_TTY,
+ Requestor = PAM_RUSER,
+ Host = PAM_RHOST,
+ Conv = PAM_CONV,
+#ifdef __LIBPAM_VERSION
+ //Fail_Delay = PAM_FAIL_DELAY
+#endif
+ };
+
+ public:
+ Authenticator(conversation* conv, void* data=0);
+ ~Authenticator(void);
+
+ void start(const std::string& service);
+ void end(void);
+ void set_item(const ItemType item, const void* value);
+ const void* get_item(const ItemType item);
+#ifdef __LIBPAM_VERSION
+ void fail_delay(const unsigned int micro_sec);
+#endif
+ void authenticate(void);
+ void open_session(void);
+ void close_session(void);
+ void setenv(const std::string& key, const std::string& value);
+ void delenv(const std::string& key);
+ const char* getenv(const std::string& key);
+ char** getenvlist(void);
+
+ private:
+ // Explicitly disable copy constructor and copy assignment
+ Authenticator(const PAM::Authenticator&);
+ Authenticator& operator=(const PAM::Authenticator&);
+ };
+};
+
+std::ostream& operator<<( std::ostream& os, const PAM::Exception& e);
+#endif
diff -uNbr --exclude=.svn release-1.2.6/app.cpp slim-pam/app.cpp
--- release-1.2.6/app.cpp 2006-09-10 22:10:40.000000000 +0200
+++ slim-pam/app.cpp 2007-06-07 04:18:21.000000000 +0200
@@ -26,6 +26,78 @@
#include "numlock.h"
+#ifdef HAVE_SHADOW
+#include <shadow.h>
+#endif
+
+#ifdef USE_PAM
+#include <string>
+
+int conv(int num_msg, const struct pam_message **msg,
+ struct pam_response **resp, void *appdata_ptr){
+ *resp = (struct pam_response *) calloc(num_msg, sizeof(struct pam_response));
+ Panel* panel = *static_cast<Panel**>(appdata_ptr);
+ int result = PAM_SUCCESS;
+ for (int i=0; i<num_msg; i++){
+ resp[i]->resp=0;
+ resp[i]->resp_retcode=0;
+ switch(msg[i]->msg_style){
+ case PAM_PROMPT_ECHO_ON:
+ // We assume PAM is asking for the username
+ panel->EventHandler(Panel::Get_Name);
+ switch(panel->getAction()){
+ case Panel::Suspend:
+ case Panel::Halt:
+ case Panel::Reboot:
+ resp[i]->resp=strdup("root");
+ break;
+
+ case Panel::Console:
+ case Panel::Exit:
+ case Panel::Login:
+ resp[i]->resp=strdup(panel->GetName().c_str());
+ break;
+ }
+ break;
+
+ case PAM_PROMPT_ECHO_OFF:
+ // We assume PAM is asking for the password
+ switch(panel->getAction()){
+ case Panel::Console:
+ case Panel::Exit:
+ // We should leave now!
+ result=PAM_CONV_ERR;
+ break;
+
+ default:
+ panel->EventHandler(Panel::Get_Passwd);
+ resp[i]->resp=strdup(panel->GetPasswd().c_str());
+ break;
+ }
+ break;
+
+ case PAM_ERROR_MSG:
+ case PAM_TEXT_INFO:
+ // We simply write these to the log
+ // TODO: Maybe we should simply ignore them
+ cerr << APPNAME << ": " << msg[i]->msg << endl;
+ break;
+ }
+ if (result!=PAM_SUCCESS) break;
+ }
+ if (result!=PAM_SUCCESS){
+ for (int i=0; i<num_msg; i++){
+ if (resp[i]->resp==0) continue;
+ free(resp[i]->resp);
+ resp[i]->resp=0;
+ };
+ free(*resp);
+ *resp=0;
+ };
+ return result;
+}
+#endif
+
extern App* LoginApp;
void CatchSignal(int sig) {
@@ -53,8 +125,12 @@
}
-App::App(int argc, char** argv) {
-
+#ifdef USE_PAM
+App::App(int argc, char** argv):
+ pam(conv, static_cast<void*>(&LoginPanel)){
+#else
+App::App(int argc, char** argv){
+#endif
int tmp;
ServerPID = -1;
testing = false;
@@ -133,6 +209,20 @@
}
}
+#ifdef USE_PAM
+ try{
+ pam.start("slim");
+ pam.set_item(PAM::Authenticator::TTY, DisplayName);
+ pam.set_item(PAM::Authenticator::Requestor, "root");
+ pam.set_item(PAM::Authenticator::Host, "localhost");
+
+ }
+ catch(PAM::Exception& e){
+ cerr << APPNAME << ": " << e << endl;
+ exit(ERR_EXIT);
+ };
+#endif
+
bool loaded = false;
while (!loaded) {
themedir = themebase + themeName;
@@ -219,9 +308,8 @@
LoginPanel = new Panel(Dpy, Scr, Root, cfg, themedir);
// Start looping
- XEvent event;
int panelclosed = 1;
- int Action;
+ Panel::ActionType Action;
bool firstloop = true; // 1st time panel is shown (for automatic username)
while(1) {
@@ -239,53 +327,124 @@
LoginPanel->OpenPanel();
}
- Action = WAIT;
- LoginPanel->GetInput()->Reset();
+ LoginPanel->Reset();
if (firstloop && cfg->getOption("default_user") != "") {
- LoginPanel->GetInput()->SetName(cfg->getOption("default_user") );
+ LoginPanel->SetName(cfg->getOption("default_user") );
firstloop = false;
}
- while(Action == WAIT) {
- XNextEvent(Dpy, &event);
- Action = LoginPanel->EventHandler(&event);
- }
- if(Action == FAIL) {
+ if (!AuthenticateUser()){
panelclosed = 0;
LoginPanel->ClearPanel();
XBell(Dpy, 100);
- } else {
+ continue;
+ }
+
+
+ Action = LoginPanel->getAction();
// for themes test we just quit
if (testing) {
- Action = EXIT;
+ Action = Panel::Exit;
}
panelclosed = 1;
LoginPanel->ClosePanel();
switch(Action) {
- case LOGIN:
+ case Panel::Login:
Login();
break;
- case CONSOLE:
+ case Panel::Console:
Console();
break;
- case REBOOT:
+ case Panel::Reboot:
Reboot();
break;
- case HALT:
+ case Panel::Halt:
Halt();
break;
- case SUSPEND:
+ case Panel::Suspend:
Suspend();
break;
- case EXIT:
+ case Panel::Exit:
Exit();
break;
}
}
+}
+
+#ifdef USE_PAM
+bool App::AuthenticateUser(void){
+ // Reset the username
+ try{
+ pam.set_item(PAM::Authenticator::User, 0);
+ pam.authenticate();
+ }
+ catch(PAM::Auth_Exception& e){
+ switch(LoginPanel->getAction()){
+ case Panel::Exit:
+ case Panel::Console:
+ return true; // <--- This is simply fake!
+ default:
+ break;
+ };
+ cerr << APPNAME << ": " << e << endl;
+ return false;
+ }
+ catch(PAM::Exception& e){
+ cerr << APPNAME << ": " << e << endl;
+ exit(ERR_EXIT);
+ };
+ return true;
+}
+#else
+bool App::AuthenticateUser(void){
+ LoginPanel->EventHandler(Panel::Get_Name);
+ switch(LoginPanel->getAction()){
+ case Panel::Exit:
+ case Panel::Console:
+ cerr << APPNAME << ": Got a special command (" << LoginPanel->GetName() << ")" << endl;
+ return true; // <--- This is simply fake!
+ default:
+ break;
+ };
+ LoginPanel->EventHandler(Panel::Get_Passwd);
+
+ char *encrypted, *correct;
+ struct passwd *pw;
+
+ switch(LoginPanel->getAction()){
+ case Panel::Suspend:
+ case Panel::Halt:
+ case Panel::Reboot:
+ pw = getpwnam("root");
+ break;
+ case Panel::Console:
+ case Panel::Exit:
+ case Panel::Login:
+ pw = getpwnam(LoginPanel->GetName().c_str());
+ break;
}
+ endpwent();
+ if(pw == 0)
+ return false;
+
+#ifdef HAVE_SHADOW
+ struct spwd *sp = getspnam(pw->pw_name);
+ endspent();
+ if(sp)
+ correct = sp->sp_pwdp;
+ else
+#endif // HAVE_SHADOW
+ correct = pw->pw_passwd;
+
+ if(correct == 0 || correct[0] == '\0')
+ return true;
+
+ encrypted = crypt(LoginPanel->GetPasswd().c_str(), correct);
+ return ((strcmp(encrypted, correct) == 0) ? true : false);
}
+#endif
int App::GetServerPID() {
@@ -313,15 +472,85 @@
struct passwd *pw;
pid_t pid;
- pw = LoginPanel->GetInput()->GetPasswdStruct();
+#ifdef USE_PAM
+ try{
+ pam.open_session();
+ pw = getpwnam(static_cast<const char*>(pam.get_item(PAM::Authenticator::User)));
+ }
+ catch(PAM::Cred_Exception& e){
+ // Credentials couldn't be established
+ cerr << APPNAME << ": " << e << endl;
+ return;
+ }
+ catch(PAM::Exception& e){
+ cerr << APPNAME << ": " << e << endl;
+ exit(ERR_EXIT);
+ };
+#else
+ pw = getpwnam(LoginPanel->GetName().c_str());
+#endif
+ endpwent();
if(pw == 0)
return;
+ if (pw->pw_shell[0] == '\0') {
+ setusershell();
+ strcpy(pw->pw_shell, getusershell());
+ endusershell();
+ }
+
+ // Setup the environment
+ char* term = getenv("TERM");
+ string maildir = _PATH_MAILDIR;
+ maildir.append("/");
+ maildir.append(pw->pw_name);
+ string xauthority = pw->pw_dir;
+ xauthority.append("/.Xauthority");
+
+#ifdef USE_PAM
+ // Setup the PAM environment
+ try{
+ if(term) pam.setenv("TERM", term);
+ pam.setenv("HOME", pw->pw_dir);
+ pam.setenv("SHELL", pw->pw_shell);
+ pam.setenv("USER", pw->pw_name);
+ pam.setenv("LOGNAME", pw->pw_name);
+ pam.setenv("PATH", cfg->getOption("default_path").c_str());
+ pam.setenv("DISPLAY", DisplayName);
+ pam.setenv("MAIL", maildir.c_str());
+ pam.setenv("XAUTHORITY", xauthority.c_str());
+ }
+ catch(PAM::Exception& e){
+ cerr << APPNAME << ": " << e << endl;
+ exit(ERR_EXIT);
+ }
+#endif
// Create new process
pid = fork();
if(pid == 0) {
+#ifdef USE_PAM
+ // Get a copy of the environment and close the child's copy
+ // of the PAM-handle.
+ char** child_env = pam.getenvlist();
+ pam.end();
+#else
+ const int Num_Of_Variables = 10; // Number of env. variables + 1
+ char** child_env = static_cast<char**>(malloc(sizeof(char*)*Num_Of_Variables));
+ int n = 0;
+ if(term) child_env[n++]=StrConcat("TERM=", term);
+ child_env[n++]=StrConcat("HOME=", pw->pw_dir);
+ child_env[n++]=StrConcat("SHELL=", pw->pw_shell);
+ child_env[n++]=StrConcat("USER=", pw->pw_name);
+ child_env[n++]=StrConcat("LOGNAME=", pw->pw_name);
+ child_env[n++]=StrConcat("PATH=", cfg->getOption("default_path").c_str());
+ child_env[n++]=StrConcat("DISPLAY=", DisplayName);
+ child_env[n++]=StrConcat("MAIL=", maildir.c_str());
+ child_env[n++]=StrConcat("XAUTHORITY=", xauthority.c_str());
+ child_env[n++]=0;
+#endif
+
// Login process starts here
- SwitchUser Su(pw, cfg, DisplayName);
+ SwitchUser Su(pw, cfg, DisplayName, child_env);
string session = LoginPanel->getSession();
string loginCommand = cfg->getOption("login_cmd");
replaceVariables(loginCommand, SESSION_VAR, session);
@@ -332,7 +561,7 @@
system(sessStart.c_str());
}
Su.Login(loginCommand.c_str(), mcookie.c_str());
- exit(OK_EXIT);
+ _exit(OK_EXIT);
}
#ifndef XNEST_DEBUG
@@ -347,6 +576,7 @@
}
if (WIFEXITED(status) && WEXITSTATUS(status)) {
LoginPanel->Message("Failed to execute login command");
+ sleep(3);
} else {
string sessStop = cfg->getOption("sessionstop_cmd");
if (sessStop != "") {
@@ -355,7 +585,16 @@
}
}
- // Close all clients
+#ifdef USE_PAM
+ try{
+ pam.close_session();
+ }
+ catch(PAM::Exception& e){
+ cerr << APPNAME << ": " << e << endl;
+ };
+#endif
+
+// Close all clients
KillAllClients(False);
KillAllClients(True);
@@ -382,6 +621,15 @@
// Stop alarm clock
alarm(0);
+#ifdef USE_PAM
+ try{
+ pam.end();
+ }
+ catch(PAM::Exception& e){
+ cerr << APPNAME << ": " << e << endl;
+ };
+#endif
+
// Write message
LoginPanel->Message((char*)cfg->getOption("reboot_msg").c_str());
sleep(3);
@@ -398,6 +646,15 @@
// Stop alarm clock
alarm(0);
+#ifdef USE_PAM
+ try{
+ pam.end();
+ }
+ catch(PAM::Exception& e){
+ cerr << APPNAME << ": " << e << endl;
+ };
+#endif
+
// Write message
LoginPanel->Message((char*)cfg->getOption("shutdown_msg").c_str());
sleep(3);
@@ -433,6 +690,15 @@
void App::Exit() {
+#ifdef USE_PAM
+ try{
+ pam.end();
+ }
+ catch(PAM::Exception& e){
+ cerr << APPNAME << ": " << e << endl;
+ };
+#endif
+
if (testing) {
char* testmsg = "This is a test message :-)";
LoginPanel->Message(testmsg);
@@ -453,6 +720,15 @@
}
void App::RestartServer() {
+#ifdef USE_PAM
+ try{
+ pam.end();
+ }
+ catch(PAM::Exception& e){
+ cerr << APPNAME << ": " << e << endl;
+ };
+#endif
+
StopServer();
RemoveLock();
Run();
diff -uNbr --exclude=.svn release-1.2.6/app.h slim-pam/app.h
--- release-1.2.6/app.h 2006-09-10 12:05:34.000000000 +0200
+++ slim-pam/app.h 2007-05-19 21:26:29.000000000 +0200
@@ -24,6 +24,10 @@
#include "cfg.h"
#include "image.h"
+#ifdef USE_PAM
+#include "PAM.h"
+#endif
+
class App {
public:
App(int argc, char** argv);
@@ -53,6 +57,8 @@
char* StrConcat(const char* str1, const char* str2);
void UpdatePid();
+ bool AuthenticateUser(void);
+
static std::string findValidRandomTheme(const std::string& set);
static void replaceVariables(std::string& input,
const std::string& var,
@@ -71,6 +77,10 @@
int ServerPID;
char* DisplayName;
+#ifdef USE_PAM
+ PAM::Authenticator pam;
+#endif
+
// Options
char* DispName;
diff -uNbr --exclude=.svn release-1.2.6/cfg.cpp slim-pam/cfg.cpp
--- release-1.2.6/cfg.cpp 2006-09-10 12:05:34.000000000 +0200
+++ slim-pam/cfg.cpp 2007-05-27 15:44:12.000000000 +0200
@@ -19,7 +19,9 @@
typedef pair<string,string> option;
-Cfg::Cfg() {
+Cfg::Cfg()
+ : currentSession(-1)
+{
// Configuration options
options.insert(option("default_path","./:/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin"));
options.insert(option("default_xserver","/usr/X11R6/bin/X"));
@@ -34,7 +36,7 @@
options.insert(option("sessionstart_cmd",""));
options.insert(option("sessionstop_cmd",""));
options.insert(option("console_cmd","/usr/X11R6/bin/xterm -C -fg white -bg black +sb -g %dx%d+%d+%d -fn %dx%d -T ""Console login"" -e /bin/sh -c ""/bin/cat /etc/issue; exec /bin/login"""));
- options.insert(option("screenshot_cmd","import -window root /login.app.png"));
+ options.insert(option("screenshot_cmd","import -window root /slim.png"));
options.insert(option("welcome_msg","Welcome to %host"));
options.insert(option("default_user",""));
options.insert(option("current_theme","default"));
@@ -129,6 +131,7 @@
}
}
cfgfile.close();
+ split(sessions, getOption("sessions"), ',', false);
return true;
} else {
error = "Cannot read configuration file: " + configfile;
@@ -211,8 +214,7 @@
int n = -1;
n = position.find("%");
if (n>0) { // X Position expressed in percentage
- const char* tmp = position.substr(0, n).c_str();
- int result = (max*string2int(tmp)/100) - (width / 2);
+ int result = (max*string2int(position.substr(0, n).c_str())/100) - (width / 2);
return result < 0 ? 0 : result ;
} else { // Absolute X position
return string2int(position.c_str());
@@ -220,17 +222,21 @@
}
// split a comma separated string into a vector of strings
-void Cfg::split(vector<string>& v, const string& str, char c) {
+void Cfg::split(vector<string>& v, const string& str, char c, bool useEmpty) {
v.clear();
string::const_iterator s = str.begin();
+ string tmp;
while (true) {
string::const_iterator begin = s;
while (*s != c && s != str.end()) { ++s; }
- v.push_back(string(begin, s));
+ tmp = string(begin, s);
+ if (useEmpty || tmp.size() > 0)
+ v.push_back(tmp);
if (s == str.end()) {
break;
}
if (++s == str.end()) {
+ if (useEmpty)
v.push_back("");
break;
}
@@ -238,15 +244,9 @@
}
string Cfg::nextSession(string current) {
- vector<string> sessions;
- split(sessions, getOption("sessions"), ',');
- if (sessions.size() <= 1)
+ if (sessions.size() < 1)
return current;
- for (int i=0; i<(int)sessions.size()-1; i++) {
- if (current == sessions[i]) {
- return sessions[i+1];
- }
- }
- return sessions[0];
+ currentSession = (currentSession + 1) % sessions.size();
+ return sessions[currentSession];
}
diff -uNbr --exclude=.svn release-1.2.6/cfg.h slim-pam/cfg.h
--- release-1.2.6/cfg.h 2006-09-10 12:05:34.000000000 +0200
+++ slim-pam/cfg.h 2007-05-17 16:38:53.000000000 +0200
@@ -37,13 +37,16 @@
static int absolutepos(const string& position, int max, int width);
static int string2int(const char* string, bool* ok = 0);
- static void split(vector<string>& v, const string& str, char c);
+ static void split(vector<string>& v, const string& str,
+ char c, bool useEmpty=true);
static string Trim(const string& s);
string nextSession(string current);
private:
map<string,string> options;
+ vector<string> sessions;
+ int currentSession;
string error;
};
diff -uNbr --exclude=.svn release-1.2.6/const.h slim-pam/const.h
--- release-1.2.6/const.h 2006-01-08 15:35:03.000000000 +0100
+++ slim-pam/const.h 2007-05-17 16:38:53.000000000 +0200
@@ -26,15 +26,6 @@
#define HIDE 0
#define SHOW 1
-#define WAIT 0
-#define LOGIN 1
-#define FAIL 2
-#define CONSOLE 3
-#define REBOOT 4
-#define HALT 5
-#define EXIT 6
-#define SUSPEND 7
-
#define GET_NAME 0
#define GET_PASSWD 1
diff -uNbr --exclude=.svn release-1.2.6/panel.cpp slim-pam/panel.cpp
--- release-1.2.6/panel.cpp 2006-09-10 12:05:34.000000000 +0200
+++ slim-pam/panel.cpp 2007-05-19 21:26:29.000000000 +0200
@@ -76,7 +76,8 @@
panelpng = themedir + "/panel.jpg";
loaded = image->Read(panelpng.c_str());
if (!loaded) {
- cerr << APPNAME << ": could not load panel image for theme '"
+ cerr << APPNAME
+ << ": could not load panel image for theme '"
<< basename((char*)themedir.c_str()) << "'"
<< endl;
exit(ERR_EXIT);
@@ -92,7 +93,8 @@
panelpng = themedir + "/background.jpg";
loaded = bg->Read(panelpng.c_str());
if (!loaded){
- cerr << APPNAME << ": could not load background image for theme '"
+ cerr << APPNAME
+ << ": could not load background image for theme '"
<< basename((char*)themedir.c_str()) << "'"
<< endl;
exit(ERR_EXIT);
@@ -106,12 +108,14 @@
} else if (bgstyle == "center") {
string hexvalue = cfg->getOption("background_color");
hexvalue = hexvalue.substr(1,6);
- bg->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
+ bg->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)),
+ XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
hexvalue.c_str());
} else { // plain color or error
string hexvalue = cfg->getOption("background_color");
hexvalue = hexvalue.substr(1,6);
- bg->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
+ bg->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)),
+ XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
hexvalue.c_str());
}
@@ -128,9 +132,6 @@
// Read (and substitute vars in) the welcome message
welcome_message = cfg->getWelcomeMessage();
intro_message = cfg->getOption("intro_msg");
-
- // Init In
- In = new Input(cfg);
}
Panel::~Panel() {
@@ -144,7 +145,6 @@
XftFontClose(Dpy, introfont);
XftFontClose(Dpy, welcomefont);
XftFontClose(Dpy, enterfont);
- delete In;
delete image;
}
@@ -182,7 +182,7 @@
void Panel::ClearPanel() {
session = "";
- In->Reset();
+ Reset();
XClearWindow(Dpy, Root);
XClearWindow(Dpy, Win);
Cursor(SHOW);
@@ -190,13 +190,13 @@
XFlush(Dpy);
}
-void Panel::Message(const char* text) {
+void Panel::Message(const string& text) {
string cfgX, cfgY;
XGlyphInfo extents;
XftDraw *draw = XftDrawCreate(Dpy, Root,
DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr));
- XftTextExtents8(Dpy, msgfont, (XftChar8*)text,
- strlen(text), &extents);
+ XftTextExtents8(Dpy, msgfont, reinterpret_cast<const XftChar8*>(text.c_str()),
+ text.length(), &extents);
cfgX = cfg->getOption("msg_x");
cfgY = cfg->getOption("msg_y");
int shadowXOffset =
@@ -208,14 +208,14 @@
int msg_y = Cfg::absolutepos(cfgY, XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)), extents.height);
SlimDrawString8 (draw, &msgcolor, msgfont, msg_x, msg_y,
- (XftChar8*)text, strlen(text),
+ text,
&msgshadowcolor,
shadowXOffset, shadowYOffset);
XFlush(Dpy);
XftDrawDestroy(draw);
}
-void Panel::Error(const char* text) {
+void Panel::Error(const string& text) {
ClosePanel();
Message(text);
sleep(ERROR_DURATION);
@@ -224,10 +224,6 @@
}
-Input* Panel::GetInput() {
- return In;
-}
-
unsigned long Panel::GetColor(const char* colorname) {
XColor color;
XWindowAttributes attributes;
@@ -244,31 +240,24 @@
}
void Panel::Cursor(int visible) {
- char* text;
+ const char* text;
int xx, yy, y2, cheight;
char* txth = "Wj"; // used to get cursor height
- switch(In->GetField()) {
- case GET_PASSWD:
- text = In->GetHiddenPasswd();
+ switch(field) {
+ case Get_Passwd:
+ text = HiddenPasswdBuffer.c_str();
xx = input_pass_x;
yy = input_pass_y;
break;
- case GET_NAME:
- text = In->GetName();
+ case Get_Name:
+ text = NameBuffer.c_str();
xx = input_name_x;
yy = input_name_y;
break;
-
- default: /* Origin & NULL string as default values. */
- text = (char *)NULL;
- xx = (int)0;
- yy = (int)0;
- break;
}
-
XGlyphInfo extents;
XftTextExtents8(Dpy, font, (XftChar8*)txth, strlen(txth), &extents);
cheight = extents.height;
@@ -288,49 +277,53 @@
}
}
-int Panel::EventHandler(XEvent* event) {
- Action = WAIT;
-
- switch(event->type) {
+void Panel::EventHandler(const Panel::FieldType& curfield) {
+ XEvent event;
+ field=curfield;
+ bool loop = true;
+ OnExpose();
+ while(loop) {
+ XNextEvent(Dpy, &event);
+ switch(event.type) {
case Expose:
- OnExpose(event);
+ OnExpose();
break;
case KeyPress:
- OnKeyPress(event);
+ loop=OnKeyPress(event);
break;
}
+ }
- return Action;
+ return;
}
-void Panel::OnExpose(XEvent* event) {
- char* name = In->GetName();
- char* passwd = In->GetHiddenPasswd();
+void Panel::OnExpose(void) {
XftDraw *draw = XftDrawCreate(Dpy, Win,
DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr));
+ XClearWindow(Dpy, Win);
if (input_pass_x != input_name_x || input_pass_y != input_name_y){
SlimDrawString8 (draw, &inputcolor, font, input_name_x, input_name_y,
- (XftChar8*)name, strlen(name),
+ NameBuffer,
&inputshadowcolor,
inputShadowXOffset, inputShadowYOffset);
SlimDrawString8 (draw, &inputcolor, font, input_pass_x, input_pass_y,
- (XftChar8*)passwd, strlen(passwd),
+ HiddenPasswdBuffer,
&inputshadowcolor,
inputShadowXOffset, inputShadowYOffset);
} else { //single input mode
- switch(In->GetField()) {
- case GET_PASSWD:
+ switch(field) {
+ case Get_Passwd:
SlimDrawString8 (draw, &inputcolor, font,
input_pass_x, input_pass_y,
- (XftChar8*)passwd, strlen(passwd),
+ HiddenPasswdBuffer,
&inputshadowcolor,
inputShadowXOffset, inputShadowYOffset);
break;
- case GET_NAME:
+ case Get_Name:
SlimDrawString8 (draw, &inputcolor, font,
input_name_x, input_name_y,
- (XftChar8*)name, strlen(name),
+ NameBuffer,
&inputshadowcolor,
inputShadowXOffset, inputShadowYOffset);
break;
@@ -342,108 +335,153 @@
ShowText();
}
-void Panel::OnKeyPress(XEvent* event) {
- char del;
- char buffer;
+bool Panel::OnKeyPress(XEvent& event) {
+ char ascii;
KeySym keysym;
XComposeStatus compstatus;
int xx;
int yy;
- char* text;
-
- bool singleInputMode =
- input_name_x == input_pass_x &&
- input_name_y == input_pass_y;
- Cursor(HIDE);
- XLookupString(&event->xkey, &buffer, 1, &keysym, &compstatus);
- del = In->Key(buffer, keysym, singleInputMode);
- Action = In->GetAction();
-
- XGlyphInfo extents;
- XftDraw *draw = XftDrawCreate(Dpy, Win,
- DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr));
+ string text;
+ string formerString = "";
- if (keysym == XK_F1) {
+ XLookupString(&event.xkey, &ascii, 1, &keysym, &compstatus);
+ switch(keysym){
+ case XK_F1:
SwitchSession();
- }
+ return true;
- bool clearField = false;
- string formerString = "";
- if ((((XKeyEvent*)event)->state & ControlMask)) {
- if (keysym == XK_w || keysym == XK_u) {
- clearField = true;
- }
- }
+ case XK_F11:
+ // Take a screenshot
+ system(cfg->getOption("screenshot_cmd").c_str());
+ return true;
+
+ case XK_Return:
+ case XK_KP_Enter:
+ if (field==Get_Name){
+ // Don't allow an empty username
+ if (NameBuffer.empty()) return true;
+
+ if (NameBuffer==CONSOLE_STR){
+ action = Console;
+ } else if (NameBuffer==HALT_STR){
+ action = Halt;
+ } else if (NameBuffer==REBOOT_STR){
+ action = Reboot;
+ } else if (NameBuffer==SUSPEND_STR){
+ action = Suspend;
+ } else if (NameBuffer==EXIT_STR){
+ action = Exit;
+ } else{
+ action = Login;
+ }
+ };
+ return false;
+ default:
+ break;
+ };
- switch(In->GetField()) {
+ Cursor(HIDE);
+ switch(keysym){
+ case XK_Delete:
+ case XK_BackSpace:
+ switch(field) {
+ case GET_NAME:
+ if (! NameBuffer.empty()){
+ formerString=NameBuffer;
+ NameBuffer.erase(--NameBuffer.end());
+ };
+ break;
case GET_PASSWD:
- if (strlen(In->GetHiddenPasswd()) == 0){
- // clear name and welcome label if we just entered the
- // password field
- if (singleInputMode) {
- xx = input_name_x;
- yy = input_name_y;
- text = In->GetName();
- XftTextExtents8(Dpy, font, (XftChar8*)text,
- strlen(text), &extents);
- XClearWindow(Dpy, Win);
- ShowText();
- }
- }
+ if (! PasswdBuffer.empty()){
+ formerString=HiddenPasswdBuffer;
+ PasswdBuffer.erase(--PasswdBuffer.end());
+ HiddenPasswdBuffer.erase(--HiddenPasswdBuffer.end());
+ };
+ break;
+ };
+ break;
- if (clearField) {
- formerString = In->GetHiddenPasswd();
- In->ResetPassword();
- }
- text = In->GetHiddenPasswd();
- xx = input_pass_x;
- yy = input_pass_y;
+ case XK_w:
+ case XK_u:
+ if (reinterpret_cast<XKeyEvent&>(event).state & ControlMask) {
+ switch(field) {
+ case Get_Passwd:
+ formerString = HiddenPasswdBuffer;
+ HiddenPasswdBuffer.clear();
+ PasswdBuffer.clear();
break;
- case GET_NAME:
- if (clearField) {
- formerString = In->GetName();
- In->ResetName();
+ case Get_Name:
+ formerString = NameBuffer;
+ NameBuffer.clear();
+ break;
+ };
+ break;
}
- text = In->GetName();
+ // Deliberate fall-through
+
+ default:
+ if (isprint(ascii) && (keysym < XK_Shift_L || keysym > XK_Hyper_R)){
+ switch(field) {
+ case GET_NAME:
+ formerString=NameBuffer;
+ if (NameBuffer.length() < INPUT_MAXLENGTH_NAME-1){
+ NameBuffer.append(&ascii,1);
+ };
+ break;
+ case GET_PASSWD:
+ formerString=HiddenPasswdBuffer;
+ if (PasswdBuffer.length() < INPUT_MAXLENGTH_NAME-1){
+ PasswdBuffer.append(&ascii,1);
+ HiddenPasswdBuffer.append("*");
+ };
+ break;
+ };
+ };
+ break;
+ };
+
+ XGlyphInfo extents;
+ XftDraw *draw = XftDrawCreate(Dpy, Win,
+ DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr));
+
+ switch(field) {
+ case Get_Name:
+ text = NameBuffer;
xx = input_name_x;
yy = input_name_y;
break;
- default: /* Origin & NULL string as default values. */
- text = (char *)NULL;
- xx = (int)0;
- yy = (int)0;
+ case Get_Passwd:
+ text = HiddenPasswdBuffer;
+ xx = input_pass_x;
+ yy = input_pass_y;
break;
}
+ if (!formerString.empty()){
char* txth = "Wj"; // get proper maximum height ?
- XftTextExtents8(Dpy, font, (XftChar8*)txth, strlen(txth), &extents);
+ XftTextExtents8(Dpy, font, reinterpret_cast<const XftChar8*>(txth), strlen(txth), &extents);
int maxHeight = extents.height;
- string tmp = "";
- if (clearField) {
- tmp = formerString;
- } else {
- tmp = text;
- tmp = tmp + del;
- }
- XftTextExtents8(Dpy, font, (XftChar8*)tmp.c_str(),
- strlen(tmp.c_str()), &extents);
+ XftTextExtents8(Dpy, font, reinterpret_cast<const XftChar8*>(formerString.c_str()),
+ formerString.length(), &extents);
int maxLength = extents.width;
XClearArea(Dpy, Win, xx-3, yy-maxHeight-3,
maxLength+6, maxHeight+6, false);
+ }
- if (!clearField) {
+ if (!text.empty()) {
SlimDrawString8 (draw, &inputcolor, font, xx, yy,
- (XftChar8*)text, strlen(text),
+ text,
&inputshadowcolor,
inputShadowXOffset, inputShadowYOffset);
}
XftDrawDestroy (draw);
Cursor(SHOW);
+ return true;
}
// Draw welcome and "enter username" message
@@ -471,14 +509,13 @@
if (welcome_x >= 0 && welcome_y >= 0) {
SlimDrawString8 (draw, &welcomecolor, welcomefont,
welcome_x, welcome_y,
- (XftChar8*)welcome_message.c_str(),
- strlen(welcome_message.c_str()),
+ welcome_message,
&welcomeshadowcolor, shadowXOffset, shadowYOffset);
}
/* Enter username-password message */
string msg;
- if (!singleInputMode|| In->GetField() == GET_PASSWD ) {
+ if (!singleInputMode|| field == Get_Passwd ) {
msg = cfg->getOption("password_msg");
XftTextExtents8(Dpy, enterfont, (XftChar8*)msg.c_str(),
strlen(msg.c_str()), &extents);
@@ -492,11 +529,10 @@
password_y = Cfg::absolutepos(cfgY, image->Height(), extents.height);
if (password_x >= 0 && password_y >= 0){
SlimDrawString8 (draw, &entercolor, enterfont, password_x, password_y,
- (XftChar8*)msg.c_str(), strlen(msg.c_str()),
- &entershadowcolor, shadowXOffset, shadowYOffset);
+ msg, &entershadowcolor, shadowXOffset, shadowYOffset);
}
}
- if (!singleInputMode|| In->GetField() == GET_NAME ) {
+ if (!singleInputMode|| field == Get_Name ) {
msg = cfg->getOption("username_msg");
XftTextExtents8(Dpy, enterfont, (XftChar8*)msg.c_str(),
strlen(msg.c_str()), &extents);
@@ -510,8 +546,7 @@
username_y = Cfg::absolutepos(cfgY, image->Height(), extents.height);
if (username_x >= 0 && username_y >= 0){
SlimDrawString8 (draw, &entercolor, enterfont, username_x, username_y,
- (XftChar8*)msg.c_str(), strlen(msg.c_str()),
- &entershadowcolor, shadowXOffset, shadowYOffset);
+ msg, &entershadowcolor, shadowXOffset, shadowYOffset);
}
}
XftDrawDestroy(draw);
@@ -524,29 +559,29 @@
// choose next available session type
void Panel::SwitchSession() {
session = cfg->nextSession(session);
- //TODO: get sessions from cfg and cycle to the next one
+ if (session.size() > 0) {
ShowSession();
+ }
}
// Display session type on the screen
void Panel::ShowSession() {
XClearWindow(Dpy, Root);
string currsession = "Session: " + session;
- char* text = (char*) currsession.c_str();
XGlyphInfo extents;
XftDraw *draw = XftDrawCreate(Dpy, Root,
DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr));
- XftTextExtents8(Dpy, msgfont, (XftChar8*)text,
- strlen(text), &extents);
+ XftTextExtents8(Dpy, msgfont, reinterpret_cast<const XftChar8*>(currsession.c_str()),
+ currsession.length(), &extents);
int msg_x = Cfg::absolutepos("50%", XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), extents.width);
int msg_y = XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)) - extents.height -100;
int shadowXOffset =
- Cfg::string2int(cfg->getOption("welcome_shadow_xoffset").c_str());
+ Cfg::string2int(cfg->getOption("msg_shadow_xoffset").c_str());
int shadowYOffset =
- Cfg::string2int(cfg->getOption("welcome_shadow_yoffset").c_str());
+ Cfg::string2int(cfg->getOption("msg_shadow_yoffset").c_str());
SlimDrawString8(draw, &msgcolor, msgfont, msg_x, msg_y,
- (XftChar8*)text, strlen(text),
+ currsession,
&msgshadowcolor,
shadowXOffset, shadowYOffset);
XFlush(Dpy);
@@ -555,13 +590,44 @@
void Panel::SlimDrawString8(XftDraw *d, XftColor *color, XftFont *font,
- int x, int y, XftChar8 *string, int len,
+ int x, int y, const string& str,
XftColor* shadowColor,
int xOffset, int yOffset)
{
if (xOffset && yOffset) {
XftDrawString8(d, shadowColor, font, x+xOffset, y+yOffset,
- string, len);
+ reinterpret_cast<const FcChar8*>(str.c_str()), str.length());
}
- XftDrawString8(d, color, font, x, y, string, len);
+ XftDrawString8(d, color, font, x, y, reinterpret_cast<const FcChar8*>(str.c_str()), str.length());
}
+
+
+Panel::ActionType Panel::getAction(void) const{
+ return action;
+};
+
+
+void Panel::Reset(void){
+ ResetName();
+ ResetPasswd();
+};
+
+void Panel::ResetName(void){
+ NameBuffer.clear();
+};
+
+void Panel::ResetPasswd(void){
+ PasswdBuffer.clear();
+ HiddenPasswdBuffer.clear();
+};
+
+void Panel::SetName(const string& name){
+ NameBuffer=name;
+ return;
+};
+const string& Panel::GetName(void) const{
+ return NameBuffer;
+};
+const string& Panel::GetPasswd(void) const{
+ return PasswdBuffer;
+};
diff -uNbr --exclude=.svn release-1.2.6/panel.h slim-pam/panel.h
--- release-1.2.6/panel.h 2006-08-18 19:21:59.000000000 +0200
+++ slim-pam/panel.h 2007-05-17 16:38:53.000000000 +0200
@@ -13,49 +13,71 @@
#define _PANEL_H_
#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include <X11/Xft/Xft.h>
#include <X11/cursorfont.h>
#include <X11/Xmu/WinUtil.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <signal.h>
#include <iostream>
+#include <string>
#ifdef NEEDS_BASENAME
#include <libgen.h>
#endif
#include "switchuser.h"
-#include "input.h"
#include "const.h"
#include "image.h"
class Panel {
public:
+ enum ActionType {
+ Login,
+ Console,
+ Reboot,
+ Halt,
+ Exit,
+ Suspend
+ };
+ enum FieldType {
+ Get_Name,
+ Get_Passwd
+ };
+
+
Panel(Display* dpy, int scr, Window root, Cfg* config,
const string& themed);
~Panel();
void OpenPanel();
void ClosePanel();
void ClearPanel();
- void Message(const char* text);
- void Error(const char* text);
- Input* GetInput();
- int EventHandler(XEvent* event);
+ void Message(const string& text);
+ void Error(const string& text);
+ void EventHandler(const FieldType& curfield);
string getSession();
+ ActionType getAction(void) const;
+ void Reset(void);
+ void ResetName(void);
+ void ResetPasswd(void);
+ void SetName(const string& name);
+ const string& GetName(void) const;
+ const string& GetPasswd(void) const;
private:
Panel();
void Cursor(int visible);
unsigned long GetColor(const char* colorname);
- void OnExpose(XEvent* event);
- void OnKeyPress(XEvent* event);
+ void OnExpose(void);
+ bool OnKeyPress(XEvent& event);
void ShowText();
void SwitchSession();
void ShowSession();
- void SlimDrawString8(XftDraw* d, XftColor* color, XftFont* font,
- int x, int y, XftChar8 *string, int len,
+ void SlimDrawString8(XftDraw *d, XftColor *color, XftFont *font,
+ int x, int y, const string& str,
XftColor* shadowColor,
int xOffset, int yOffset);
@@ -82,7 +104,13 @@
XftFont* enterfont;
XftColor entercolor;
XftColor entershadowcolor;
- int Action;
+ ActionType action;
+ FieldType field;
+
+ // Username/Password
+ string NameBuffer;
+ string PasswdBuffer;
+ string HiddenPasswdBuffer;
// Configuration
int input_name_x;
@@ -110,9 +138,6 @@
// Pixmap data
Pixmap PanelPixmap;
- // Name/Passwd handler
- Input* In;
-
Image* image;
// For thesting themes
diff -uNbr --exclude=.svn release-1.2.6/switchuser.cpp slim-pam/switchuser.cpp
--- release-1.2.6/switchuser.cpp 2006-08-18 19:10:29.000000000 +0200
+++ slim-pam/switchuser.cpp 2007-05-19 21:26:29.000000000 +0200
@@ -13,10 +13,12 @@
using namespace std;
-SwitchUser::SwitchUser(struct passwd *pw, Cfg *c, const string& display)
+SwitchUser::SwitchUser(struct passwd *pw, Cfg *c, const string& display,
+ char** _env)
: cfg(c),
Pw(pw),
- displayName(display)
+ displayName(display),
+ env(_env)
{
}
@@ -27,33 +29,12 @@
void SwitchUser::Login(const char* cmd, const char* mcookie) {
- SetEnvironment();
SetUserId();
SetClientAuth(mcookie);
Execute(cmd);
}
-void SwitchUser::SetEnvironment() {
- char *term = getenv("TERM");
- char** environ;
- environ = (char **) new char*[2];
- environ[0] = 0;
- if(term)
- putenv(StrConcat("TERM=", term));
- putenv(StrConcat("HOME=", Pw->pw_dir));
- putenv(StrConcat("SHELL=", Pw->pw_shell));
- putenv(StrConcat("USER=", Pw->pw_name));
- putenv(StrConcat("LOGNAME=", Pw->pw_name));
- putenv(StrConcat("PATH=", cfg->getOption("default_path").c_str()));
- putenv(StrConcat("DISPLAY=", displayName.c_str()));
- putenv(StrConcat("MAIL="_PATH_MAILDIR"/", Pw->pw_name));
- putenv(StrConcat("XAUTHORITY=", StrConcat(Pw->pw_dir,"/.Xauthority")));
- /* putenv("XAUTHORITY=/tmp/serverauth"); */
- chdir(Pw->pw_dir);
-}
-
-
void SwitchUser::SetUserId() {
if( (Pw == 0) ||
(initgroups(Pw->pw_name, Pw->pw_gid) != 0) ||
@@ -66,42 +47,11 @@
void SwitchUser::Execute(const char* cmd) {
- char *args[4];
- char* shell = strdup(Pw->pw_shell);
- char *shell_basename = BaseName(shell);
-
- args[0] = new char[strlen(shell_basename) + 2];
- strcpy(args[0], "-");
- strcat(args[0], shell_basename);
- args[1] = "-c";
- args[2] = (char*)cmd;
- args[3] = 0;
-
- execv(shell, args);
+ chdir(Pw->pw_dir);
+ execle(Pw->pw_shell, Pw->pw_shell, "-c", cmd, NULL, env);
cerr << APPNAME << ": could not execute login command" << endl;
}
-
-char* SwitchUser::BaseName(const char* name) {
- const char *base = name;
-
- while(*name) {
- if(*name == '/')
- base = name + 1;
- ++name;
- }
-
- return (char*) base;
-}
-
-
-char* SwitchUser::StrConcat(const char* str1, const char* str2) {
- char* tmp = new char[strlen(str1) + strlen(str2) + 1];
- strcpy(tmp, str1);
- strcat(tmp, str2);
- return tmp;
-}
-
void SwitchUser::SetClientAuth(const char* mcookie) {
int r;
string home = string(Pw->pw_dir);
diff -uNbr --exclude=.svn release-1.2.6/switchuser.h slim-pam/switchuser.h
--- release-1.2.6/switchuser.h 2006-07-15 02:33:52.000000000 +0200
+++ slim-pam/switchuser.h 2007-05-19 21:26:29.000000000 +0200
@@ -25,7 +25,8 @@
class SwitchUser {
public:
- SwitchUser(struct passwd *pw, Cfg *c, const std::string& display);
+ SwitchUser(struct passwd *pw, Cfg *c, const std::string& display,
+ char** _env);
~SwitchUser();
void Login(const char* cmd, const char* mcookie);
@@ -34,13 +35,12 @@
void SetEnvironment();
void SetUserId();
void Execute(const char* cmd);
- char* BaseName(const char* name);
- char* StrConcat(const char* str1, const char* str2);
void SetClientAuth(const char* mcookie);
Cfg* cfg;
struct passwd *Pw;
std::string displayName;
+ char** env;
};
Index: slim.spec
===================================================================
RCS file: /cvs/pkgs/rpms/slim/F-7/slim.spec,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- slim.spec 3 Sep 2007 19:37:32 -0000 1.2
+++ slim.spec 24 Sep 2007 19:52:58 -0000 1.3
@@ -1,6 +1,6 @@
Name: slim
Version: 1.2.6
-Release: 6%{?dist}
+Release: 7%{?dist}
Summary: Simple Login Manager
Group: User Interface/X
@@ -17,6 +17,7 @@
Patch0: slim-1.2.6-make.patch
Patch1: slim-1.2.6-usexwd.patch
Patch2: slim-1.2.6-fedora.patch
+Patch3: slim-1.2.6-pam.patch
BuildRequires: libXmu-devel libXft-devel libXrender-devel
BuildRequires: libpng-devel libjpeg-devel freetype-devel fontconfig-devel
@@ -46,9 +47,10 @@
%patch2 -p1 -b .fedora
sed -e 's@/usr/X11R6/bin@%{_bindir}@g' -i.orig slim.conf
cp -p %{SOURCE3} README.Fedora
+%patch3 -p1 -b .pam
%build
-make %{?_smp_mflags} OPTFLAGS="$RPM_OPT_FLAGS"
+make %{?_smp_mflags} OPTFLAGS="$RPM_OPT_FLAGS" USE_PAM=1
%install
rm -rf $RPM_BUILD_ROOT
@@ -96,6 +98,10 @@
%changelog
+* Mon Sep 24 2007 Anders F Bjorklund <afb at users.sourceforge.net> 1.2.6-7
+- backport PAM support from "slim-pam" branch, USE_PAM=1
+- backport fix for segfault on exit when testing themes.
+
* Mon Aug 6 2007 Anders F Bjorklund <afb at users.sourceforge.net> 1.2.6-6
- require system-logos instead of fedora-logos (#250365)
More information about the fedora-extras-commits
mailing list