# From http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=529306 # Commited to upstream. diff --git a/Makefile b/Makefile index a01bafd..9bd5555 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ CXX=/usr/bin/g++ CC=/usr/bin/gcc CFLAGS=-Wall -I. -I/usr/include/freetype2 -I/usr/include/freetype2/config -I/usr/include/libpng12 -I/usr/include CXXFLAGS=$(CFLAGS) -LDFLAGS=-L/usr/X11R6/lib -lXft -lX11 -lpng12 -lm -lXmu -lpng -ljpeg +LDFLAGS=-L/usr/X11R6/lib -lXft -lX11 -lpng12 -lm -lXmu -lpng -ljpeg -lrt CUSTOM=-DHAVE_SHADOW ifdef USE_PAM LDFLAGS+= -lpam @@ -25,7 +25,8 @@ VERSION=1.3.1 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 app.o panel.o +OBJECTS=jpeg.o png.o main.o image.o numlock.o cfg.o switchuser.o app.o \ + panel.o util.o ifdef USE_PAM OBJECTS+=PAM.o endif diff --git a/Makefile.freebsd b/Makefile.freebsd index 3ff326e..c925a39 100644 --- a/Makefile.freebsd +++ b/Makefile.freebsd @@ -24,7 +24,8 @@ VERSION=1.3.1 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 app.o panel.o +OBJECTS=jpeg.o png.o main.o image.o numlock.o cfg.o switchuser.o app.o \ + panel.o util.o .ifdef USE_PAM OBJECTS+=PAM.o .endif diff --git a/Makefile.netbsd b/Makefile.netbsd index ad8bb8b..45f33e6 100644 --- a/Makefile.netbsd +++ b/Makefile.netbsd @@ -24,7 +24,8 @@ VERSION=1.3.1 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 app.o panel.o +OBJECTS=jpeg.o png.o main.o image.o numlock.o cfg.o switchuser.o app.o \ + panel.o util.o .ifdef USE_PAM OBJECTS+=PAM.o .endif diff --git a/Makefile.openbsd b/Makefile.openbsd index b1829f8..1205b84 100644 --- a/Makefile.openbsd +++ b/Makefile.openbsd @@ -20,7 +20,8 @@ VERSION=1.3.1 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 app.o panel.o +OBJECTS=jpeg.o png.o main.o image.o numlock.o cfg.o switchuser.o app.o \ + util.o panel.o .SUFFIXES: .c.o .cpp.o diff --git a/app.cpp b/app.cpp index 83ae947..0ac8c3a 100644 --- a/app.cpp +++ b/app.cpp @@ -24,6 +24,7 @@ #include #include "app.h" #include "numlock.h" +#include "util.h" #ifdef HAVE_SHADOW @@ -128,15 +129,18 @@ void User1Signal(int sig) { #ifdef USE_PAM -App::App(int argc, char** argv): - pam(conv, static_cast(&LoginPanel)){ +App::App(int argc, char** argv) + : pam(conv, static_cast(&LoginPanel)), #else -App::App(int argc, char** argv){ +App::App(int argc, char** argv) + : #endif + mcookiesize(32) // Must be divisible by 4 +{ int tmp; ServerPID = -1; testing = false; - mcookie = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + mcookie = string(App::mcookiesize, 'a'); daemonmode = false; force_nodaemon = false; firstlogin = true; @@ -1127,13 +1131,13 @@ string App::findValidRandomTheme(const string& set) name = name.substr(0, name.length() - 1); } - srandom(getpid()+time(NULL)); + Util::srandom(Util::makeseed()); vector themes; string themefile; Cfg::split(themes, name, ','); do { - int sel = random() % themes.size(); + int sel = Util::random() % themes.size(); name = Cfg::Trim(themes[sel]); themefile = string(THEMESDIR) +"/" + name + THEMESFILE; @@ -1160,33 +1164,33 @@ void App::replaceVariables(string& input, } +/* + * We rely on the fact that all bits generated by Util::random() + * are usable, so we are taking full words from its output. + */ void App::CreateServerAuth() { /* create mit cookie */ - int i, r; - int hexcount = 0; - string authfile; - string cmd; + uint16_t word; + uint8_t hi, lo; + int i; + string authfile; const char *digits = "0123456789abcdef"; - srand( time(NULL) ); - for ( i = 0; i < 31; i++ ) { - r = rand()%16; - mcookie[i] = digits[r]; - if (r>9) - hexcount++; + Util::srandom(Util::makeseed()); + for (i = 0; i < App::mcookiesize; i+=4) { + word = Util::random() & 0xffff; + lo = word & 0xff; + hi = word >> 8; + mcookie[i] = digits[lo & 0x0f]; + mcookie[i+1] = digits[lo >> 4]; + mcookie[i+2] = digits[hi & 0x0f]; + mcookie[i+3] = digits[hi >> 4]; } - /* MIT-COOKIE: even occurrences of digits and hex digits */ - if ((hexcount%2) == 0) { - r = rand()%10; - } else { - r = rand()%5+10; - } - mcookie[31] = digits[r]; /* reinitialize auth file */ authfile = cfg->getOption("authfile"); remove(authfile.c_str()); putenv(StrConcat("XAUTHORITY=", authfile.c_str())); - cmd = cfg->getOption("xauth_path") + " -q -f " + authfile + " add :0 . " + mcookie; - system(cmd.c_str()); + Util::add_mcookie(mcookie, ":0", cfg->getOption("xauth_path"), + authfile); } char* App::StrConcat(const char* str1, const char* str2) { diff --git a/app.h b/app.h index 7b4bd10..9a44269 100644 --- a/app.h +++ b/app.h @@ -101,6 +101,8 @@ private: std::string themeName; std::string mcookie; + + const int mcookiesize; }; diff --git a/switchuser.cpp b/switchuser.cpp index e72a8fc..ec298e1 100644 --- a/switchuser.cpp +++ b/switchuser.cpp @@ -10,6 +10,7 @@ */ #include "switchuser.h" +#include "util.h" using namespace std; @@ -53,10 +54,10 @@ void SwitchUser::Execute(const char* cmd) { } void SwitchUser::SetClientAuth(const char* mcookie) { - int r; + bool r; string home = string(Pw->pw_dir); string authfile = home + "/.Xauthority"; remove(authfile.c_str()); - string cmd = cfg->getOption("xauth_path") + " -q -f " + authfile + " add :0 . " + mcookie; - r = system(cmd.c_str()); + r = Util::add_mcookie(mcookie, ":0", cfg->getOption("xauth_path"), + authfile); } diff --git a/util.cpp b/util.cpp new file mode 100644 index 0000000..5ed972f --- /dev/null +++ b/util.cpp @@ -0,0 +1,69 @@ +/* SLiM - Simple Login Manager + Copyright (C) 2009 Eygene Ryabinkin + + 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 + +#include +#include +#include +#include + +#include "util.h" + +/* + * Adds the given cookie to the specified Xauthority file. + * Returns true on success, false on fault. + */ +bool Util::add_mcookie(const std::string &mcookie, const char *display, + const std::string &xauth_cmd, const std::string &authfile) +{ + FILE *fp; + std::string cmd = xauth_cmd + " -f " + authfile + " -q"; + + fp = popen(cmd.c_str(), "w"); + if (!fp) + return false; + fprintf(fp, "remove %s\n", display); + fprintf(fp, "add %s %s %s\n", display, ".", mcookie.c_str()); + fprintf(fp, "exit\n"); + + pclose(fp); + return true; +} + +/* + * Interface for random number generator. Just now it uses ordinary + * random/srandom routines and serves as a wrapper for them. + */ +void Util::srandom(unsigned long seed) +{ + ::srandom(seed); +} + +long Util::random(void) +{ + return ::random(); +} + +/* + * Makes seed for the srandom() using "random" values obtained from + * getpid(), time(NULL) and others. + */ +long Util::makeseed(void) +{ + struct timespec ts; + long pid = getpid(); + long tm = time(NULL); + + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { + ts.tv_sec = ts.tv_nsec = 0; + } + + return pid + tm + (ts.tv_sec ^ ts.tv_nsec); +} diff --git a/util.h b/util.h new file mode 100644 index 0000000..b8d2993 --- /dev/null +++ b/util.h @@ -0,0 +1,24 @@ +/* SLiM - Simple Login Manager + Copyright (C) 2009 Eygene Ryabinkin + + 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 __UTIL_H__ +#define __UTIL_H__ + +#include + +namespace Util { + bool add_mcookie(const std::string &mcookie, const char *display, + const std::string &xauth_cmd, const std::string &authfile); + + void srandom(unsigned long seed); + long random(void); + + long makeseed(void); +}; + +#endif /* __UTIL_H__ */