Browse Source

Imported Upstream version 1.3.6

tags/upstream/1.3.6
Mateusz Łukasik 6 years ago
parent
commit
3fa315f70b
31 changed files with 4595 additions and 3646 deletions
  1. +85
    -12
      CMakeLists.txt
  2. +10
    -0
      ChangeLog
  3. +78
    -78
      Ck.cpp
  4. +26
    -26
      Ck.h
  5. +246
    -248
      PAM.cpp
  6. +66
    -66
      PAM.h
  7. +988
    -998
      app.cpp
  8. +66
    -66
      app.h
  9. +277
    -239
      cfg.cpp
  10. +24
    -24
      cfg.h
  11. +17
    -19
      const.h
  12. +825
    -770
      image.cpp
  13. +62
    -61
      image.h
  14. +83
    -83
      jpeg.c
  15. +2
    -5
      log.cpp
  16. +28
    -22
      log.h
  17. +13
    -12
      main.cpp
  18. +43
    -43
      numlock.cpp
  19. +15
    -15
      numlock.h
  20. +843
    -548
      panel.cpp
  21. +150
    -120
      panel.h
  22. +150
    -145
      png.c
  23. +9
    -0
      slim.service
  24. +61
    -0
      slimlock.1
  25. +11
    -0
      slimlock.conf
  26. +370
    -0
      slimlock.cpp
  27. +2
    -0
      slimlock.pam
  28. +24
    -25
      switchuser.cpp
  29. +15
    -15
      switchuser.h
  30. +1
    -1
      util.cpp
  31. +5
    -5
      util.h

+ 85
- 12
CMakeLists.txt View File

@@ -18,12 +18,13 @@ INCLUDE(CheckTypeSize)
# Version
set(SLIM_VERSION_MAJOR "1")
set(SLIM_VERSION_MINOR "3")
set(SLIM_VERSION_PATCH "4")
set(SLIM_VERSION_PATCH "6")
set(SLIM_VERSION "${SLIM_VERSION_MAJOR}.${SLIM_VERSION_MINOR}.${SLIM_VERSION_PATCH}")

set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "Installation Directory")
set(PKGDATADIR "${CMAKE_INSTALL_PREFIX}/share/slim")
set(SYSCONFDIR "/etc")
set(LIBDIR "/lib")
set(MANDIR "${CMAKE_INSTALL_PREFIX}/share/man")

set(SLIM_DEFINITIONS)
@@ -42,32 +43,56 @@ set(SLIM_DEFINITIONS ${SLIM_DEFINITIONS} "-DPKGDATADIR=\"${PKGDATADIR}\"")
set(SLIM_DEFINITIONS ${SLIM_DEFINITIONS} "-DSYSCONFDIR=\"${SYSCONFDIR}\"")

# Flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -g -O2" )
set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -Wall -g -O2" )
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -g -O2")
set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -Wall -g -O2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -g -O2")

# source
set(slim_srcs
main.cpp
app.cpp
cfg.cpp
image.cpp
numlock.cpp
panel.cpp
switchuser.cpp
util.cpp
log.cpp
png.c
jpeg.c
)

set(slimlock_srcs
slimlock.cpp
)

set(common_srcs
cfg.cpp
image.cpp
log.cpp
panel.cpp
util.cpp
)
if(USE_PAM)
set(slim_srcs ${slim_srcs} PAM.cpp)
set(common_srcs ${common_srcs} PAM.cpp)
# for now, only build slimlock if we are using PAM.
set(BUILD_SLIMLOCK 1)
endif(USE_PAM)

# Build common library
set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries")

if (BUILD_SHARED_LIBS)
message(STATUS "Enable shared library building")
add_library(libslim ${common_srcs})
else(BUILD_SHARED_LIBS)
message(STATUS "Disable shared library building")
add_library(libslim STATIC ${common_srcs})
endif(BUILD_SHARED_LIBS)

if(USE_CONSOLEKIT)
set(slim_srcs ${slim_srcs} Ck.cpp)
endif(USE_CONSOLEKIT)

add_executable(${PROJECT_NAME} ${slim_srcs})
if(BUILD_SLIMLOCK)
add_executable(slimlock ${slimlock_srcs})
endif(BUILD_SLIMLOCK)

#Set the custom CMake module directory where our include/lib finders are
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules")
@@ -95,6 +120,7 @@ if(USE_PAM)
message("\tPAM Found")
set(SLIM_DEFINITIONS ${SLIM_DEFINITIONS} "-DUSE_PAM")
target_link_libraries(${PROJECT_NAME} ${PAM_LIBRARY})
target_link_libraries(slimlock ${PAM_LIBRARY})
include_directories(${PAM_INCLUDE_DIR})
else(PAM_FOUND)
message("\tPAM Not Found")
@@ -134,6 +160,7 @@ endif(USE_CONSOLEKIT)
find_library(M_LIB m)
find_library(RT_LIB rt)
find_library(CRYPTO_LIB crypt)
find_package(Threads)

add_definitions(${SLIM_DEFINITIONS})

@@ -142,6 +169,7 @@ include_directories(
${X11_INCLUDE_DIR}
${X11_Xft_INCLUDE_PATH}
${X11_Xrender_INCLUDE_PATH}
${X11_Xrandr_INCLUDE_PATH}
${FREETYPE_INCLUDE_DIR_freetype2}
${X11_Xmu_INCLUDE_PATH}
${ZLIB_INCLUDE_DIR}
@@ -149,7 +177,12 @@ include_directories(
${PNG_INCLUDE_DIR}
)

#Set up library with all found packages
target_link_libraries(libslim
${JPEG_LIBRARIES}
${PNG_LIBRARIES}
)

#Set up library with all found packages for slim
target_link_libraries(${PROJECT_NAME}
${M_LIB}
${RT_LIB}
@@ -157,18 +190,58 @@ target_link_libraries(${PROJECT_NAME}
${X11_X11_LIB}
${X11_Xft_LIB}
${X11_Xrender_LIB}
${X11_Xrandr_LIB}
${X11_Xmu_LIB}
${FREETYPE_LIBRARY}
${JPEG_LIBRARIES}
${PNG_LIBRARIES}
)
libslim
)

if(BUILD_SLIMLOCK)
#Set up library with all found packages for slimlock
target_link_libraries(slimlock
${M_LIB}
${RT_LIB}
${CRYPTO_LIB}
${X11_X11_LIB}
${X11_Xft_LIB}
${X11_Xrender_LIB}
${X11_Xrandr_LIB}
${X11_Xmu_LIB}
${X11_Xext_LIB}
${FREETYPE_LIBRARY}
${JPEG_LIBRARIES}
${PNG_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
libslim
)
endif(BUILD_SLIMLOCK)

####### install
# slim
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin )
install(TARGETS slim RUNTIME DESTINATION bin)
install(TARGETS slimlock RUNTIME DESTINATION bin)

if (BUILD_SHARED_LIBS)
set_target_properties(libslim PROPERTIES
OUTPUT_NAME slim
SOVERSION ${SLIM_VERSION})

install(TARGETS libslim
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
endif (BUILD_SHARED_LIBS)

# man file
install(FILES slim.1 DESTINATION ${MANDIR}/man1/)
install(FILES slimlock.1 DESTINATION ${MANDIR}/man1/)
# configure
install(FILES slim.conf DESTINATION ${SYSCONFDIR})
# systemd service file
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
install(FILES slim.service DESTINATION ${LIBDIR}/systemd/system)
endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
# themes directory
subdirs(themes)

+ 10
- 0
ChangeLog View File

@@ -1,3 +1,13 @@
1.3.6 - 2013.10.01
* Merge slimlock.
* Add support ^H (like backspace).
* And fix some bugs.

1.3.5 - 2012.12.31
* Support UTF8 string.
* Add systemd service.
* And fix some bugs.

1.3.4 - 2012.06.26
* Replaced stderr writes function.
* Fix numlock control.


+ 78
- 78
Ck.cpp View File

@@ -19,128 +19,128 @@

namespace Ck {
Exception::Exception(const std::string &func,
const std::string &errstr):
func(func),
errstr(errstr)
const std::string &errstr):
func(func),
errstr(errstr)
{}

dbus_bool_t Session::ck_connector_open_graphic_session(const std::string &display,
uid_t uid)
uid_t uid)
{
dbus_bool_t local = true;
const char *session_type = "x11";
const char *x11_display = display.c_str();
const char *x11_device = get_x11_device(display);
const char *remote_host = "";
const char *display_dev = "";
return ck_connector_open_session_with_parameters(ckc, &error,
"unix-user", &uid,
"session-type", &session_type,
"x11-display", &x11_display,
"x11-display-device", &x11_device,
"display-device", &display_dev,
"remote-host-name", &remote_host,
"is-local", &local,
NULL);
dbus_bool_t local = true;
const char *session_type = "x11";
const char *x11_display = display.c_str();
const char *x11_device = get_x11_device(display);
const char *remote_host = "";
const char *display_dev = "";
return ck_connector_open_session_with_parameters(ckc, &error,
"unix-user", &uid,
"session-type", &session_type,
"x11-display", &x11_display,
"x11-display-device", &x11_device,
"display-device", &display_dev,
"remote-host-name", &remote_host,
"is-local", &local,
NULL);
}

const char * Session::get_x11_device(const std::string &display)
{
static char device[32];
static char device[32];

Display *xdisplay = XOpenDisplay(display.c_str());
Display *xdisplay = XOpenDisplay(display.c_str());

if(!xdisplay)
throw Exception(__func__, "cannot open display");
if(!xdisplay)
throw Exception(__func__, "cannot open display");

Window root;
Atom xfree86_vt_atom;
Atom return_type_atom;
int return_format;
unsigned long return_count;
unsigned long bytes_left;
unsigned char *return_value;
long vt;
Window root;
Atom xfree86_vt_atom;
Atom return_type_atom;
int return_format;
unsigned long return_count;
unsigned long bytes_left;
unsigned char *return_value;
long vt;

xfree86_vt_atom = XInternAtom(xdisplay, "XFree86_VT", true);
xfree86_vt_atom = XInternAtom(xdisplay, "XFree86_VT", true);

if(xfree86_vt_atom == None)
throw Exception(__func__, "cannot get XFree86_VT");
if(xfree86_vt_atom == None)
throw Exception(__func__, "cannot get XFree86_VT");

root = DefaultRootWindow(xdisplay);
root = DefaultRootWindow(xdisplay);

if(XGetWindowProperty(xdisplay, root, xfree86_vt_atom,
0L, 1L, false, XA_INTEGER,
&return_type_atom, &return_format,
&return_count, &bytes_left,
&return_value) != Success)
throw Exception(__func__, "cannot get root window property");
if(XGetWindowProperty(xdisplay, root, xfree86_vt_atom,
0L, 1L, false, XA_INTEGER,
&return_type_atom, &return_format,
&return_count, &bytes_left,
&return_value) != Success)
throw Exception(__func__, "cannot get root window property");

if(return_type_atom != XA_INTEGER)
throw Exception(__func__, "bad atom type");
if(return_type_atom != XA_INTEGER)
throw Exception(__func__, "bad atom type");

if(return_format != 32)
throw Exception(__func__, "invalid return format");
if(return_format != 32)
throw Exception(__func__, "invalid return format");

if(return_count != 1)
throw Exception(__func__, "invalid count");
if(return_count != 1)
throw Exception(__func__, "invalid count");

if(bytes_left != 0)
throw Exception(__func__, "invalid bytes left");
if(bytes_left != 0)
throw Exception(__func__, "invalid bytes left");

vt = *((long *)return_value);
vt = *((long *)return_value);

std::snprintf(device, 32, "/dev/tty%ld", vt);
std::snprintf(device, 32, "/dev/tty%ld", vt);

if(return_value)
XFree(return_value);
if(return_value)
XFree(return_value);

return device;
return device;
}

void Session::open_session(const std::string &display, uid_t uid)
{
ckc = ck_connector_new();
if(!ckc)
throw Exception(__func__, "error setting up connection to ConsoleKit");
if(!ck_connector_open_graphic_session(display, uid)) {
if(dbus_error_is_set(&error))
throw Exception(__func__, error.message);
else
throw Exception(__func__, "cannot open ConsoleKit session: OOM, DBus system bus "
" not available or insufficient privileges");
}
ckc = ck_connector_new();
if(!ckc)
throw Exception(__func__, "error setting up connection to ConsoleKit");
if(!ck_connector_open_graphic_session(display, uid)) {
if(dbus_error_is_set(&error))
throw Exception(__func__, error.message);
else
throw Exception(__func__, "cannot open ConsoleKit session: OOM, DBus system bus "
" not available or insufficient privileges");
}
}

const char * Session::get_xdg_session_cookie()
{
return ck_connector_get_cookie(ckc);
return ck_connector_get_cookie(ckc);
}

void Session::close_session()
{
if(!ck_connector_close_session(ckc, &error)) {
if(dbus_error_is_set(&error))
throw Exception(__func__, error.message);
else
throw Exception(__func__, "cannot close ConsoleKit session: OOM, DBus system bus "
" not available or insufficient privileges");
}
if(!ck_connector_close_session(ckc, &error)) {
if(dbus_error_is_set(&error))
throw Exception(__func__, error.message);
else
throw Exception(__func__, "cannot close ConsoleKit session: OOM, DBus system bus "
" not available or insufficient privileges");
}
}

Session::Session()
{
dbus_error_init(&error);
dbus_error_init(&error);
}

Session::~Session()
{
dbus_error_free(&error);
dbus_error_free(&error);
}
};
}

std::ostream& operator<<( std::ostream& os, const Ck::Exception& e)
{


+ 26
- 26
Ck.h View File

@@ -16,31 +16,31 @@
#include <dbus/dbus.h>

namespace Ck {
class Exception {
public:
std::string func;
std::string errstr;
Exception(const std::string &func, const std::string &errstr);
};
class Session {
private:
CkConnector *ckc;
DBusError error;
const char * get_x11_device(const std::string &display);
dbus_bool_t ck_connector_open_graphic_session(const std::string &display,
uid_t uid);
public:
const char * get_xdg_session_cookie();
void open_session(const std::string &display, uid_t uid);
void close_session();
Session();
~Session();
};
};
std::ostream& operator<<( std::ostream& os, const Ck::Exception& e);
class Exception {
public:
std::string func;
std::string errstr;
Exception(const std::string &func, const std::string &errstr);
};
class Session {
private:
CkConnector *ckc;
DBusError error;
const char * get_x11_device(const std::string &display);
dbus_bool_t ck_connector_open_graphic_session(const std::string &display,
uid_t uid);
public:
const char * get_xdg_session_cookie();
void open_session(const std::string &display, uid_t uid);
void close_session();
Session();
~Session();
};
}
std::ostream &operator<<(std::ostream &os, const Ck::Exception &e);

#endif /* _CK_H_ */

+ 246
- 248
PAM.cpp View File

@@ -11,265 +11,263 @@
#include "PAM.h"

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:
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:
case PAM_BAD_ITEM:
#endif
_end();
throw Exception(pam_handle, "pam_get_item()", last_result);
_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;
}
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;
}
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:
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:
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:
_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:
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);
}

};
_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;
os << e.func_name << ": " << e.errstr;
return os;
}

+ 66
- 66
PAM.h View File

@@ -17,83 +17,83 @@
#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 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 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 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;
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);
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,
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
/* 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);
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);
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);
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&);
};
};
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
#endif /* _PAM_H_ */

+ 988
- 998
app.cpp
File diff suppressed because it is too large
View File


+ 66
- 66
app.h View File

@@ -13,6 +13,7 @@
#define _APP_H_

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
@@ -33,87 +34,86 @@

class App {
public:
App(int argc, char** argv);
~App();
void Run();
int GetServerPID();
void RestartServer();
void StopServer();
App(int argc, char **argv);
~App();
void Run();
int GetServerPID();
void RestartServer();
void StopServer();

// Lock functions
void GetLock();
void RemoveLock();
/* Lock functions */
void GetLock();
void RemoveLock();

bool isServerStarted();
bool isServerStarted();

private:
void Login();
void Reboot();
void Halt();
void Suspend();
void Console();
void Exit();
void KillAllClients(Bool top);
void ReadConfig();
void OpenLog();
void CloseLog();
void HideCursor();
void CreateServerAuth();
char* StrConcat(const char* str1, const char* str2);
void UpdatePid();
bool AuthenticateUser(bool focuspass);
static std::string findValidRandomTheme(const std::string& set);
static void replaceVariables(std::string& input,
const std::string& var,
const std::string& value);
// Server functions
int StartServer();
int ServerTimeout(int timeout, char *string);
int WaitForServer();
// Private data
Window Root;
Display* Dpy;
int Scr;
Panel* LoginPanel;
int ServerPID;
const char* DisplayName;
bool serverStarted;
void Login();
void Reboot();
void Halt();
void Suspend();
void Console();
void Exit();
void KillAllClients(Bool top);
void ReadConfig();
void OpenLog();
void CloseLog();
void HideCursor();
void CreateServerAuth();
char *StrConcat(const char *str1, const char *str2);
void UpdatePid();
bool AuthenticateUser(bool focuspass);
static std::string findValidRandomTheme(const std::string &set);
static void replaceVariables(std::string &input,
const std::string &var,
const std::string &value);
/* Server functions */
int StartServer();
int ServerTimeout(int timeout, char *string);
int WaitForServer();
/* Private data */
Window Root;
Display *Dpy;
int Scr;
Panel *LoginPanel;
int ServerPID;
const char *DisplayName;
bool serverStarted;

#ifdef USE_PAM
PAM::Authenticator pam;
#endif
#ifdef USE_CONSOLEKIT
Ck::Session ck;
Ck::Session ck;
#endif

// Options
char* DispName;
/* Options */
char *DispName;

Cfg *cfg;
Cfg *cfg;

Pixmap BackgroundPixmap;
Pixmap BackgroundPixmap;

void blankScreen();
Image* image;
void setBackground(const std::string& themedir);
void blankScreen();
Image *image;
Atom BackgroundPixmapId;
void setBackground(const std::string &themedir);

bool firstlogin;
bool daemonmode;
bool force_nodaemon;
// For testing themes
char* testtheme;
bool testing;
std::string themeName;
std::string mcookie;

const int mcookiesize;
};
bool firstlogin;
bool daemonmode;
bool force_nodaemon;
/* For testing themes */
char *testtheme;
bool testing;

std::string themeName;
std::string mcookie;

#endif
const int mcookiesize;
};

#endif /* _APP_H_ */

+ 277
- 239
cfg.cpp View File

@@ -1,6 +1,7 @@
/* SLiM - Simple Login Manager
Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
Copyright (C) 2012-13 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>

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
@@ -24,288 +25,325 @@ using namespace std;

typedef pair<string,string> option;

Cfg::Cfg()
: currentSession(-1)
Cfg::Cfg()
: currentSession(-1)
{
// Configuration options
options.insert(option("default_path","/bin:/usr/bin:/usr/local/bin"));
options.insert(option("default_xserver","/usr/bin/X"));
options.insert(option("xserver_arguments",""));
options.insert(option("numlock",""));
options.insert(option("daemon",""));
options.insert(option("xauth_path","/usr/bin/xauth"));
options.insert(option("login_cmd","exec /bin/bash -login ~/.xinitrc %session"));
options.insert(option("halt_cmd","/sbin/shutdown -h now"));
options.insert(option("reboot_cmd","/sbin/shutdown -r now"));
options.insert(option("suspend_cmd",""));
options.insert(option("sessionstart_cmd",""));
options.insert(option("sessionstop_cmd",""));
options.insert(option("console_cmd","/usr/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 /slim.png"));
options.insert(option("welcome_msg","Welcome to %host"));
options.insert(option("session_msg","Session:"));
options.insert(option("default_user",""));
options.insert(option("focus_password","no"));
options.insert(option("auto_login","no"));
options.insert(option("current_theme","default"));
options.insert(option("lockfile","/var/run/slim.lock"));
options.insert(option("logfile","/var/log/slim.log"));
options.insert(option("authfile","/var/run/slim.auth"));
options.insert(option("shutdown_msg","The system is halting..."));
options.insert(option("reboot_msg","The system is rebooting..."));
options.insert(option("sessions","wmaker,blackbox,icewm"));
options.insert(option("sessiondir",""));
options.insert(option("hidecursor","false"));

// Theme stuff
options.insert(option("input_panel_x","50%"));
options.insert(option("input_panel_y","40%"));
options.insert(option("input_name_x","200"));
options.insert(option("input_name_y","154"));
options.insert(option("input_pass_x","-1")); // default is single inputbox
options.insert(option("input_pass_y","-1"));
options.insert(option("input_font","Verdana:size=11"));
options.insert(option("input_color", "#000000"));
options.insert(option("input_cursor_height","20"));
options.insert(option("input_maxlength_name","20"));
options.insert(option("input_maxlength_passwd","20"));
options.insert(option("input_shadow_xoffset", "0"));
options.insert(option("input_shadow_yoffset", "0"));
options.insert(option("input_shadow_color","#FFFFFF"));

options.insert(option("welcome_font","Verdana:size=14"));
options.insert(option("welcome_color","#FFFFFF"));
options.insert(option("welcome_x","-1"));
options.insert(option("welcome_y","-1"));
options.insert(option("welcome_shadow_xoffset", "0"));
options.insert(option("welcome_shadow_yoffset", "0"));
options.insert(option("welcome_shadow_color","#FFFFFF"));

options.insert(option("intro_msg",""));
options.insert(option("intro_font","Verdana:size=14"));
options.insert(option("intro_color","#FFFFFF"));
options.insert(option("intro_x","-1"));
options.insert(option("intro_y","-1"));

options.insert(option("background_style","stretch"));
options.insert(option("background_color","#CCCCCC"));

options.insert(option("username_font","Verdana:size=12"));
options.insert(option("username_color","#FFFFFF"));
options.insert(option("username_x","-1"));
options.insert(option("username_y","-1"));
options.insert(option("username_msg","Please enter your username"));
options.insert(option("username_shadow_xoffset", "0"));
options.insert(option("username_shadow_yoffset", "0"));
options.insert(option("username_shadow_color","#FFFFFF"));

options.insert(option("password_x","-1"));
options.insert(option("password_y","-1"));
options.insert(option("password_msg","Please enter your password"));

options.insert(option("msg_color","#FFFFFF"));
options.insert(option("msg_font","Verdana:size=16:bold"));
options.insert(option("msg_x","40"));
options.insert(option("msg_y","40"));
options.insert(option("msg_shadow_xoffset", "0"));
options.insert(option("msg_shadow_yoffset", "0"));
options.insert(option("msg_shadow_color","#FFFFFF"));

options.insert(option("session_color","#FFFFFF"));
options.insert(option("session_font","Verdana:size=16:bold"));
options.insert(option("session_x","50%"));
options.insert(option("session_y","90%"));
options.insert(option("session_shadow_xoffset", "0"));
options.insert(option("session_shadow_yoffset", "0"));
options.insert(option("session_shadow_color","#FFFFFF"));

error = "";

/* Configuration options */
options.insert(option("default_path","/bin:/usr/bin:/usr/local/bin"));
options.insert(option("default_xserver","/usr/bin/X"));
options.insert(option("xserver_arguments",""));
options.insert(option("numlock",""));
options.insert(option("daemon",""));
options.insert(option("xauth_path","/usr/bin/xauth"));
options.insert(option("login_cmd","exec /bin/bash -login ~/.xinitrc %session"));
options.insert(option("halt_cmd","/sbin/shutdown -h now"));
options.insert(option("reboot_cmd","/sbin/shutdown -r now"));
options.insert(option("suspend_cmd",""));
options.insert(option("sessionstart_cmd",""));
options.insert(option("sessionstop_cmd",""));
options.insert(option("console_cmd","/usr/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 /slim.png"));
options.insert(option("welcome_msg","Welcome to %host"));
options.insert(option("session_msg","Session:"));
options.insert(option("default_user",""));
options.insert(option("focus_password","no"));
options.insert(option("auto_login","no"));
options.insert(option("current_theme","default"));
options.insert(option("lockfile","/var/run/slim.lock"));
options.insert(option("logfile","/var/log/slim.log"));
options.insert(option("authfile","/var/run/slim.auth"));
options.insert(option("shutdown_msg","The system is halting..."));
options.insert(option("reboot_msg","The system is rebooting..."));
options.insert(option("sessiondir",""));
options.insert(option("hidecursor","false"));

/* Theme stuff */
options.insert(option("input_panel_x","50%"));
options.insert(option("input_panel_y","40%"));
options.insert(option("input_name_x","200"));
options.insert(option("input_name_y","154"));
options.insert(option("input_pass_x","-1")); /* default is single inputbox */
options.insert(option("input_pass_y","-1"));
options.insert(option("input_font","Verdana:size=11"));
options.insert(option("input_color", "#000000"));
options.insert(option("input_cursor_height","20"));
options.insert(option("input_maxlength_name","20"));
options.insert(option("input_maxlength_passwd","20"));
options.insert(option("input_shadow_xoffset", "0"));
options.insert(option("input_shadow_yoffset", "0"));
options.insert(option("input_shadow_color","#FFFFFF"));

options.insert(option("welcome_font","Verdana:size=14"));
options.insert(option("welcome_color","#FFFFFF"));
options.insert(option("welcome_x","-1"));
options.insert(option("welcome_y","-1"));
options.insert(option("welcome_shadow_xoffset", "0"));
options.insert(option("welcome_shadow_yoffset", "0"));
options.insert(option("welcome_shadow_color","#FFFFFF"));

options.insert(option("intro_msg",""));
options.insert(option("intro_font","Verdana:size=14"));
options.insert(option("intro_color","#FFFFFF"));
options.insert(option("intro_x","-1"));
options.insert(option("intro_y","-1"));

options.insert(option("background_style","stretch"));
options.insert(option("background_color","#CCCCCC"));

options.insert(option("username_font","Verdana:size=12"));
options.insert(option("username_color","#FFFFFF"));
options.insert(option("username_x","-1"));
options.insert(option("username_y","-1"));
options.insert(option("username_msg","Please enter your username"));
options.insert(option("username_shadow_xoffset", "0"));
options.insert(option("username_shadow_yoffset", "0"));
options.insert(option("username_shadow_color","#FFFFFF"));

options.insert(option("password_x","-1"));
options.insert(option("password_y","-1"));
options.insert(option("password_msg","Please enter your password"));

options.insert(option("msg_color","#FFFFFF"));
options.insert(option("msg_font","Verdana:size=16:bold"));
options.insert(option("msg_x","40"));
options.insert(option("msg_y","40"));
options.insert(option("msg_shadow_xoffset", "0"));
options.insert(option("msg_shadow_yoffset", "0"));
options.insert(option("msg_shadow_color","#FFFFFF"));

options.insert(option("session_color","#FFFFFF"));
options.insert(option("session_font","Verdana:size=16:bold"));
options.insert(option("session_x","50%"));
options.insert(option("session_y","90%"));
options.insert(option("session_shadow_xoffset", "0"));
options.insert(option("session_shadow_yoffset", "0"));
options.insert(option("session_shadow_color","#FFFFFF"));

// slimlock-specific options
options.insert(option("dpms_standby_timeout", "60"));
options.insert(option("dpms_off_timeout", "600"));
options.insert(option("wrong_passwd_timeout", "2"));
options.insert(option("passwd_feedback_x", "50%"));
options.insert(option("passwd_feedback_y", "10%"));
options.insert(option("passwd_feedback_msg", "Authentication failed"));
options.insert(option("passwd_feedback_capslock", "Authentication failed (CapsLock is on)"));
options.insert(option("show_username", "1"));
options.insert(option("show_welcome_msg", "0"));
options.insert(option("tty_lock", "1"));
options.insert(option("bell", "1"));

error = "";
}

Cfg::~Cfg() {
options.clear();
options.clear();
}
/*
* Creates the Cfg object and parses
* known options from the given configfile / themefile
*/
bool Cfg::readConf(string configfile) {
int n = -1;
string line, fn(configfile);
map<string,string>::iterator it;
string op;
ifstream cfgfile( fn.c_str() );
if (cfgfile) {
while (getline( cfgfile, line )) {
it = options.begin();
while (it != options.end()) {
op = it->first;
n = line.find(op);
if (n == 0)
options[op] = parseOption(line, op);
it++;
}
}
cfgfile.close();

fillSessionList();

return true;
} else {
error = "Cannot read configuration file: " + configfile;
return false;
}
int n = -1;
size_t pos = 0;
string line, next, op, fn(configfile);
map<string,string>::iterator it;
ifstream cfgfile(fn.c_str());

if (!cfgfile) {
error = "Cannot read configuration file: " + configfile;
return false;
}
while (getline(cfgfile, line)) {
if ((pos = line.find('\\')) != string::npos) {
if (line.length() == pos + 1) {
line.replace(pos, 1, " ");
next = next + line;
continue;
} else
line.replace(pos, line.length() - pos, " ");
}

if (!next.empty()) {
line = next + line;
next = "";
}
it = options.begin();
while (it != options.end()) {
op = it->first;
n = line.find(op);
if (n == 0)
options[op] = parseOption(line, op);
++it;
}
}
cfgfile.close();

fillSessionList();

return true;
}

/* Returns the option value, trimmed */
string Cfg::parseOption(string line, string option ) {
return Trim( line.substr(option.size(), line.size() - option.size()));
return Trim( line.substr(option.size(), line.size() - option.size()));
}


const string& Cfg::getError() const {
return error;
return error;
}

string& Cfg::getOption(string option) {
return options[option];
return options[option];
}

/* return a trimmed string */
string Cfg::Trim( const string& s ) {
if ( s.empty() ) {
return s;
}
int pos = 0;
string line = s;
int len = line.length();
while ( pos < len && isspace( line[pos] ) ) {
++pos;
}
line.erase( 0, pos );
pos = line.length()-1;
while ( pos > -1 && isspace( line[pos] ) ) {
--pos;
}
if ( pos != -1 ) {
line.erase( pos+1 );
}
return line;
if ( s.empty() ) {
return s;
}
int pos = 0;
string line = s;
int len = line.length();
while ( pos < len && isspace( line[pos] ) ) {
++pos;
}
line.erase( 0, pos );
pos = line.length()-1;
while ( pos > -1 && isspace( line[pos] ) ) {
--pos;
}
if ( pos != -1 ) {
line.erase( pos+1 );
}
return line;
}

/* Return the welcome message with replaced vars */
string Cfg::getWelcomeMessage(){
string s = getOption("welcome_msg");
int n = -1;
n = s.find("%host");
if (n >= 0) {
string tmp = s.substr(0, n);
char host[40];
gethostname(host,40);
tmp = tmp + host;
tmp = tmp + s.substr(n+5, s.size() - n);
s = tmp;
}
n = s.find("%domain");
if (n >= 0) {
string tmp = s.substr(0, n);;
char domain[40];
getdomainname(domain,40);
tmp = tmp + domain;
tmp = tmp + s.substr(n+7, s.size() - n);
s = tmp;
}
return s;
string s = getOption("welcome_msg");
int n = s.find("%host");
if (n >= 0) {
string tmp = s.substr(0, n);
char host[40];
gethostname(host,40);
tmp = tmp + host;
tmp = tmp + s.substr(n+5, s.size() - n);
s = tmp;
}
n = s.find("%domain");
if (n >= 0) {
string tmp = s.substr(0, n);;
char domain[40];
getdomainname(domain,40);
tmp = tmp + domain;
tmp = tmp + s.substr(n+7, s.size() - n);
s = tmp;
}
return s;
}

int Cfg::string2int(const char* string, bool* ok) {
char* err = 0;
int l = (int)strtol(string, &err, 10);
if (ok) {
*ok = (*err == 0);
}
return (*err == 0) ? l : 0;
char* err = 0;
int l = (int)strtol(string, &err, 10);
if (ok) {
*ok = (*err == 0);
}
return (*err == 0) ? l : 0;
}

int Cfg::getIntOption(std::string option) {
return string2int(options[option].c_str());
return string2int(options[option].c_str());
}

// Get absolute position
/* Get absolute position */
int Cfg::absolutepos(const string& position, int max, int width) {
int n = -1;
n = position.find("%");
if (n>0) { // X Position expressed in percentage
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());
}
int n = position.find("%");
if (n>0) { /* X Position expressed in percentage */
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());
}
}

// split a comma separated string into a vector of strings
/* split a comma separated string into a vector of strings */
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; }
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;
}
}
v.clear();
string::const_iterator s = str.begin();
string tmp;
while (true) {
string::const_iterator begin = s;
while (*s != c && s != str.end()) { ++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;
}
}
}

void Cfg::fillSessionList(){
string strSessionList = getOption("sessions");
string strSessionDir = getOption("sessiondir");

sessions.clear();

if( !strSessionDir.empty() ) {
DIR *pDir = opendir(strSessionDir.c_str());

if (pDir != NULL) {
struct dirent *pDirent = NULL;

while ((pDirent = readdir(pDir)) != NULL) {
string strFile(strSessionDir);
strFile += "/";
strFile += pDirent->d_name;

struct stat oFileStat;

if (stat(strFile.c_str( ), &oFileStat) == 0){
if (S_ISREG(oFileStat.st_mode) &&
access(strFile.c_str(), R_OK | X_OK) == 0){
sessions.push_back(string(pDirent->d_name));
}
}
}
closedir(pDir);
}
}

if (sessions.empty()){
split(sessions, strSessionList, ',', false);
}
string strSessionDir = getOption("sessiondir");

sessions.clear();

if( !strSessionDir.empty() ) {
DIR *pDir = opendir(strSessionDir.c_str());

if (pDir != NULL) {
struct dirent *pDirent = NULL;

while ((pDirent = readdir(pDir)) != NULL) {
string strFile(strSessionDir);
strFile += "/";
strFile += pDirent->d_name;

struct stat oFileStat;

if (stat(strFile.c_str(), &oFileStat) == 0) {
if (S_ISREG(oFileStat.st_mode) &&
access(strFile.c_str(), R_OK) == 0){
ifstream desktop_file( strFile.c_str() );
if (desktop_file){
string line, session_name = "", session_exec = "";
while (getline( desktop_file, line )) {
if (line.substr(0, 5) == "Name=") {
session_name = line.substr(5);
if (!session_exec.empty())
break;
} else
if (line.substr(0, 5) == "Exec=") {
session_exec = line.substr(5);
if (!session_name.empty())
break;
}
}
desktop_file.close();
pair<string,string> session(session_name,session_exec);
sessions.push_back(session);
cout << session_exec << " - " << session_name << endl;
}

}
}
}
closedir(pDir);
}
}

if (sessions.empty()){
pair<string,string> session("","");
sessions.push_back(session);
}
}

string Cfg::nextSession(string current) {
if (sessions.size() < 1)
return current;

currentSession = (currentSession + 1) % sessions.size();
return sessions[currentSession];
pair<string,string> Cfg::nextSession() {
currentSession = (currentSession + 1) % sessions.size();
return sessions[currentSession];
}

+ 24
- 24
cfg.h View File

@@ -15,7 +15,7 @@
#include <map>
#include <vector>

#define INPUT_MAXLENGTH_NAME 30
#define INPUT_MAXLENGTH_NAME 30
#define INPUT_MAXLENGTH_PASSWD 50

#define CFGFILE SYSCONFDIR"/slim.conf"
@@ -25,32 +25,32 @@
class Cfg {

public:
Cfg();
~Cfg();
bool readConf(std::string configfile);
std::string parseOption(std::string line, std::string option);
const std::string& getError() const;
std::string& getOption(std::string option);
int getIntOption(std::string option);
std::string getWelcomeMessage();

static int absolutepos(const std::string& position, int max, int width);
static int string2int(const char* string, bool* ok = 0);
static void split(std::vector<std::string>& v, const std::string& str,
char c, bool useEmpty=true);
static std::string Trim(const std::string& s);

std::string nextSession(std::string current);
Cfg();
~Cfg();

private:
void fillSessionList();
bool readConf(std::string configfile);
std::string parseOption(std::string line, std::string option);
const std::string& getError() const;
std::string& getOption(std::string option);
int getIntOption(std::string option);
std::string getWelcomeMessage();

static int absolutepos(const std::string &position, int max, int width);
static int string2int(const char *string, bool *ok = 0);
static void split(std::vector<std::string> &v, const std::string &str,
char c, bool useEmpty=true);
static std::string Trim(const std::string &s);

std::pair<std::string,std::string> nextSession();

private:
std::map<std::string,std::string> options;
std::vector<std::string> sessions;
int currentSession;
std::string error;
void fillSessionList();

private:
std::map<std::string,std::string> options;
std::vector<std::pair<std::string,std::string> > sessions;
int currentSession;
std::string error;
};

#endif
#endif /* _CFG_H_ */

+ 17
- 19
const.h View File

@@ -12,39 +12,37 @@
#ifndef _CONST_H_
#define _CONST_H_

#define APPNAME "slim"
#define DISPLAY ":0.0"

#define APPNAME "slim"
#define CONSOLE_STR "console"
#define HALT_STR "halt"
#define REBOOT_STR "reboot"
#define EXIT_STR "exit"
#define SUSPEND_STR "suspend"

#define DISPLAY ":0.0"
#define HIDE 0
#define SHOW 1

#define CONSOLE_STR "console"
#define HALT_STR "halt"
#define REBOOT_STR "reboot"
#define EXIT_STR "exit"
#define SUSPEND_STR "suspend"

#define HIDE 0
#define SHOW 1

#define GET_NAME 0
#define GET_NAME 0
#define GET_PASSWD 1

#define OK_EXIT 0
#define ERR_EXIT 1
#define OK_EXIT 0
#define ERR_EXIT 1

/* duration for showing error messages,
* as "login command failed", in seconds
*/
#define ERROR_DURATION 5

// variables replaced in login_cmd
#define SESSION_VAR "%session"
#define THEME_VAR "%theme"
/* variables replaced in login_cmd */
#define SESSION_VAR "%session"
#define THEME_VAR "%theme"

/* variables replaced in pre-session_cmd and post-session_cmd */
#define USER_VAR "%user"
#define USER_VAR "%user"

/* max height/width for images */
#define MAX_DIMENSION 10000

#endif
#endif /* _CONST_H_ */

+ 825
- 770
image.cpp
File diff suppressed because it is too large
View File


+ 62
- 61
image.h View File

@@ -1,15 +1,15 @@
/* SLiM - Simple Login Manager
Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
Copyright (C) 2012 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
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.
The following code has been adapted and extended from
xplanet 1.0.1, Copyright (C) 2002-04 Hari Nair <hari@alumni.caltech.edu>
Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
Copyright (C) 2012 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
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.
The following code has been adapted and extended from
xplanet 1.0.1, Copyright (C) 2002-04 Hari Nair <hari@alumni.caltech.edu>
*/

#ifndef _IMAGE_H_
@@ -21,59 +21,60 @@

class Image {
public:
Image();
Image(const int w, const int h, const unsigned char *rgb,
const unsigned char *alpha);

~Image();

const unsigned char * getPNGAlpha() const {
return(png_alpha);
};
const unsigned char * getRGBData() const {
return(rgb_data);
};

void getPixel(double px, double py, unsigned char *pixel);
void getPixel(double px, double py, unsigned char *pixel,
unsigned char *alpha);