Skip to content

Commit

Permalink
Add support ConsoleKit.
Browse files Browse the repository at this point in the history
Applied patch #3209. Thanks to gawen for the patch.

Signed-off-by: Nobuhiro Iwamatsu <[email protected]>
  • Loading branch information
iwamatsu committed Feb 14, 2012
1 parent 54eead4 commit 5cf3d4c
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 0 deletions.
28 changes: 28 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ set(slim_srcs
switchuser.cpp
util.cpp
PAM.cpp
Ck.cpp
png.c
jpeg.c
)
Expand Down Expand Up @@ -96,6 +97,33 @@ else(USE_PAM)
message("\tPAM disabled")
endif(USE_PAM)

# ConsoleKit
if(USE_CONSOLEKIT)
find_package(CkConnector)
message("\tConsoleKit Enabled")
if(CKCONNECTOR_FOUND)
message("\tConsoleKit Found")
# DBus check
find_package(DBus REQUIRED)
if(DBUS_FOUND)
message("\tDBus Found")
target_link_libraries(${PROJECT_NAME} ${DBUS_LIBRARIES})
include_directories(${DBUS_ARCH_INCLUDE_DIR})
include_directories(${DBUS_INCLUDE_DIR})
set(SLIM_DEFINITIONS ${SLIM_DEFINITIONS} "-DUSE_CONSOLEKIT")
target_link_libraries(${PROJECT_NAME} ${CKCONNECTOR_LIBRARIES})
include_directories(${CKCONNECTOR_INCLUDE_DIR})
else(DBUS_FOUND)
message("\tDBus Not Found")
endif(DBUS_FOUND)
else(CKCONNECTOR_FOUND)
message("\tConsoleKit Not Found")
message("\tConsoleKit disabled")
endif(CKCONNECTOR_FOUND)
else(USE_CONSOLEKIT)
message("\tConsoleKit disabled")
endif(USE_CONSOLEKIT)

# system librarys
find_library(M_LIB m)
find_library(RT_LIB rt)
Expand Down
149 changes: 149 additions & 0 deletions Ck.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/* SLiM - Simple Login Manager
Copyright (C) 2011 David Hauweele
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 <cstdio>
#include <iostream>

#include <ck-connector.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdarg.h>

#include "Ck.h"

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

dbus_bool_t Session::ck_connector_open_graphic_session(const std::string &display,
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);
}

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

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

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;

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

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

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(return_type_atom != XA_INTEGER)
throw Exception(__func__, "bad atom type");

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

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

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

vt = *((long *)return_value);

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

if(return_value)
XFree(return_value);

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");
}
}

const char * Session::get_xdg_session_cookie()
{
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");
}
}

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

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

std::ostream& operator<<( std::ostream& os, const Ck::Exception& e)
{
os << e.func << ": " << e.errstr;
return os;
}
46 changes: 46 additions & 0 deletions Ck.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* 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 _CK_H_
#define _CK_H_

#include <string>

#include <ck-connector.h>
#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);

#endif /* _CK_H_ */
45 changes: 45 additions & 0 deletions app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,16 +556,48 @@ void App::Login() {
}
#endif

#ifdef USE_CONSOLEKIT
// Setup the ConsoleKit session
try {
ck.open_session(DisplayName, pw->pw_uid);
}
catch(Ck::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();

# ifdef USE_CONSOLEKIT
char** old_env = child_env;

// Grow the copy of the environment for the session cookie
int n;
for(n = 0; child_env[n] != NULL ; n++);

n++;

child_env = static_cast<char**>(malloc(sizeof(char*)*n));
memcpy(child_env, old_env, sizeof(char*)*n);
child_env[n - 1] = StrConcat("XDG_SESSION_COOKIE=", ck.get_xdg_session_cookie());
child_env[n] = NULL;
# endif /* USE_CONSOLEKIT */

pam.end();
#else

# ifdef USE_CONSOLEKIT
const int Num_Of_Variables = 12; // Number of env. variables + 1
# else
const int Num_Of_Variables = 11; // Number of env. variables + 1
# endif /* USE_CONSOLEKIT */
char** child_env = static_cast<char**>(malloc(sizeof(char*)*Num_Of_Variables));
int n = 0;
if(term) child_env[n++]=StrConcat("TERM=", term);
Expand All @@ -578,7 +610,11 @@ void App::Login() {
child_env[n++]=StrConcat("DISPLAY=", DisplayName);
child_env[n++]=StrConcat("MAIL=", maildir.c_str());
child_env[n++]=StrConcat("XAUTHORITY=", xauthority.c_str());
# ifdef USE_CONSOLEKIT
child_env[n++]=StrConcat("XDG_SESSION_COOKIE=", ck.get_xdg_session_cookie());
# endif /* USE_CONSOLEKIT */
child_env[n++]=0;

#endif

// Login process starts here
Expand Down Expand Up @@ -619,6 +655,15 @@ void App::Login() {
}
}

#ifdef USE_CONSOLEKIT
try {
ck.close_session();
}
catch(Ck::Exception &e) {
cerr << APPNAME << ": " << e << endl;
};
#endif

#ifdef USE_PAM
try{
pam.close_session();
Expand Down
6 changes: 6 additions & 0 deletions app.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#ifdef USE_PAM
#include "PAM.h"
#endif
#ifdef USE_CONSOLEKIT
#include "Ck.h"
#endif

class App {
public:
Expand Down Expand Up @@ -81,6 +84,9 @@ class App {
#ifdef USE_PAM
PAM::Authenticator pam;
#endif
#ifdef USE_CONSOLEKIT
Ck::Session ck;
#endif

// Options
char* DispName;
Expand Down

0 comments on commit 5cf3d4c

Please sign in to comment.