aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnselm R Garbe <garbeam@gmail.com>2015-01-27 22:16:52 +0100
committerAnselm R Garbe <garbeam@gmail.com>2015-01-27 22:16:52 +0100
commita31b9191111572dafaa8366415b89a4472aa4626 (patch)
tree4d180d440d5d62ec7dcf3fe98ad4c05ab7d7668c
parent66e31556db4921b5f24ced47dae5e1c7ea3bd150 (diff)
applied Dimitris' style patch from Dec'14, with some minor modifications
-rw-r--r--slock.c112
1 files changed, 60 insertions, 52 deletions
diff --git a/slock.c b/slock.c
index face75e..407a540 100644
--- a/slock.c
+++ b/slock.c
@@ -1,4 +1,3 @@
1
2/* See LICENSE file for license details. */ 1/* See LICENSE file for license details. */
3#define _XOPEN_SOURCE 500 2#define _XOPEN_SOURCE 500
4#if HAVE_SHADOW_H 3#if HAVE_SHADOW_H
@@ -37,20 +36,22 @@ static int nscreens;
37static Bool running = True; 36static Bool running = True;
38 37
39static void 38static void
40die(const char *errstr, ...) { 39die(const char *errstr, ...)
40{
41 va_list ap; 41 va_list ap;
42 42
43 va_start(ap, errstr); 43 va_start(ap, errstr);
44 vfprintf(stderr, errstr, ap); 44 vfprintf(stderr, errstr, ap);
45 va_end(ap); 45 va_end(ap);
46 exit(EXIT_FAILURE); 46 exit(1);
47} 47}
48 48
49#ifdef __linux__ 49#ifdef __linux__
50#include <fcntl.h> 50#include <fcntl.h>
51 51
52static void 52static void
53dontkillme(void) { 53dontkillme(void)
54{
54 int fd; 55 int fd;
55 56
56 fd = open("/proc/self/oom_score_adj", O_WRONLY); 57 fd = open("/proc/self/oom_score_adj", O_WRONLY);
@@ -62,8 +63,10 @@ dontkillme(void) {
62#endif 63#endif
63 64
64#ifndef HAVE_BSD_AUTH 65#ifndef HAVE_BSD_AUTH
66/* only run as root */
65static const char * 67static const char *
66getpw(void) { /* only run as root */ 68getpw(void)
69{
67 const char *rval; 70 const char *rval;
68 struct passwd *pw; 71 struct passwd *pw;
69 72
@@ -73,7 +76,7 @@ getpw(void) { /* only run as root */
73 if (errno) 76 if (errno)
74 die("slock: getpwuid: %s\n", strerror(errno)); 77 die("slock: getpwuid: %s\n", strerror(errno));
75 else 78 else
76 die("slock: cannot retrieve password entry (make sure to suid or sgid slock)\n"); 79 die("slock: cannot retrieve password entry\n");
77 } 80 }
78 rval = pw->pw_passwd; 81 rval = pw->pw_passwd;
79 82
@@ -81,15 +84,15 @@ getpw(void) { /* only run as root */
81 if (rval[0] == 'x' && rval[1] == '\0') { 84 if (rval[0] == 'x' && rval[1] == '\0') {
82 struct spwd *sp; 85 struct spwd *sp;
83 sp = getspnam(getenv("USER")); 86 sp = getspnam(getenv("USER"));
84 if(!sp) 87 if (!sp)
85 die("slock: cannot retrieve shadow entry (make sure to suid or sgid slock)\n"); 88 die("slock: cannot retrieve shadow entry (make sure to suid or sgid slock)\n");
86 rval = sp->sp_pwdp; 89 rval = sp->sp_pwdp;
87 } 90 }
88#endif 91#endif
89 92
90 /* drop privileges */ 93 /* drop privileges */
91 if (geteuid() == 0 94 if (geteuid() == 0 &&
92 && ((getegid() != pw->pw_gid && setgid(pw->pw_gid) < 0) || setuid(pw->pw_uid) < 0)) 95 ((getegid() != pw->pw_gid && setgid(pw->pw_gid) < 0) || setuid(pw->pw_uid) < 0))
93 die("slock: cannot drop privileges\n"); 96 die("slock: cannot drop privileges\n");
94 return rval; 97 return rval;
95} 98}
@@ -115,21 +118,23 @@ readpw(Display *dpy, const char *pws)
115 * had been removed and you can set it with "xset" or some other 118 * had been removed and you can set it with "xset" or some other
116 * utility. This way the user can easily set a customized DPMS 119 * utility. This way the user can easily set a customized DPMS
117 * timeout. */ 120 * timeout. */
118 while(running && !XNextEvent(dpy, &ev)) { 121 while (running && !XNextEvent(dpy, &ev)) {
119 if(ev.type == KeyPress) { 122 if (ev.type == KeyPress) {
120 buf[0] = 0; 123 buf[0] = 0;
121 num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0); 124 num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0);
122 if(IsKeypadKey(ksym)) { 125 if (IsKeypadKey(ksym)) {
123 if(ksym == XK_KP_Enter) 126 if (ksym == XK_KP_Enter)
124 ksym = XK_Return; 127 ksym = XK_Return;
125 else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) 128 else if (ksym >= XK_KP_0 && ksym <= XK_KP_9)
126 ksym = (ksym - XK_KP_0) + XK_0; 129 ksym = (ksym - XK_KP_0) + XK_0;
127 } 130 }
128 if(IsFunctionKey(ksym) || IsKeypadKey(ksym) 131 if (IsFunctionKey(ksym) ||
129 || IsMiscFunctionKey(ksym) || IsPFKey(ksym) 132 IsKeypadKey(ksym) ||
130 || IsPrivateKeypadKey(ksym)) 133 IsMiscFunctionKey(ksym) ||
134 IsPFKey(ksym) ||
135 IsPrivateKeypadKey(ksym))
131 continue; 136 continue;
132 switch(ksym) { 137 switch (ksym) {
133 case XK_Return: 138 case XK_Return:
134 passwd[len] = 0; 139 passwd[len] = 0;
135#ifdef HAVE_BSD_AUTH 140#ifdef HAVE_BSD_AUTH
@@ -137,7 +142,7 @@ readpw(Display *dpy, const char *pws)
137#else 142#else
138 running = !!strcmp(crypt(passwd, pws), pws); 143 running = !!strcmp(crypt(passwd, pws), pws);
139#endif 144#endif
140 if(running) 145 if (running)
141 XBell(dpy, 100); 146 XBell(dpy, 100);
142 len = 0; 147 len = 0;
143 break; 148 break;
@@ -145,36 +150,37 @@ readpw(Display *dpy, const char *pws)
145 len = 0; 150 len = 0;
146 break; 151 break;
147 case XK_BackSpace: 152 case XK_BackSpace:
148 if(len) 153 if (len)
149 --len; 154 --len;
150 break; 155 break;
151 default: 156 default:
152 if(num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) { 157 if (num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) {
153 memcpy(passwd + len, buf, num); 158 memcpy(passwd + len, buf, num);
154 len += num; 159 len += num;
155 } 160 }
156 break; 161 break;
157 } 162 }
158 if(llen == 0 && len != 0) { 163 if (llen == 0 && len != 0) {
159 for(screen = 0; screen < nscreens; screen++) { 164 for (screen = 0; screen < nscreens; screen++) {
160 XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[1]); 165 XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[1]);
161 XClearWindow(dpy, locks[screen]->win); 166 XClearWindow(dpy, locks[screen]->win);
162 } 167 }
163 } else if(llen != 0 && len == 0) { 168 } else if (llen != 0 && len == 0) {
164 for(screen = 0; screen < nscreens; screen++) { 169 for (screen = 0; screen < nscreens; screen++) {
165 XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[0]); 170 XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[0]);
166 XClearWindow(dpy, locks[screen]->win); 171 XClearWindow(dpy, locks[screen]->win);
167 } 172 }
168 } 173 }
169 llen = len; 174 llen = len;
170 } 175 }
171 else for(screen = 0; screen < nscreens; screen++) 176 else for (screen = 0; screen < nscreens; screen++)
172 XRaiseWindow(dpy, locks[screen]->win); 177 XRaiseWindow(dpy, locks[screen]->win);
173 } 178 }
174} 179}
175 180
176static void 181static void
177unlockscreen(Display *dpy, Lock *lock) { 182unlockscreen(Display *dpy, Lock *lock)
183{
178 if(dpy == NULL || lock == NULL) 184 if(dpy == NULL || lock == NULL)
179 return; 185 return;
180 186
@@ -187,7 +193,8 @@ unlockscreen(Display *dpy, Lock *lock) {
187} 193}
188 194
189static Lock * 195static Lock *
190lockscreen(Display *dpy, int screen) { 196lockscreen(Display *dpy, int screen)
197{
191 char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; 198 char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
192 unsigned int len; 199 unsigned int len;
193 Lock *lock; 200 Lock *lock;
@@ -195,11 +202,11 @@ lockscreen(Display *dpy, int screen) {
195 XSetWindowAttributes wa; 202 XSetWindowAttributes wa;
196 Cursor invisible; 203 Cursor invisible;
197 204
198 if(dpy == NULL || screen < 0) 205 if (dpy == NULL || screen < 0)
199 return NULL; 206 return NULL;
200 207
201 lock = malloc(sizeof(Lock)); 208 lock = malloc(sizeof(Lock));
202 if(lock == NULL) 209 if (lock == NULL)
203 return NULL; 210 return NULL;
204 211
205 lock->screen = screen; 212 lock->screen = screen;
@@ -210,8 +217,8 @@ lockscreen(Display *dpy, int screen) {
210 wa.override_redirect = 1; 217 wa.override_redirect = 1;
211 wa.background_pixel = BlackPixel(dpy, lock->screen); 218 wa.background_pixel = BlackPixel(dpy, lock->screen);
212 lock->win = XCreateWindow(dpy, lock->root, 0, 0, DisplayWidth(dpy, lock->screen), DisplayHeight(dpy, lock->screen), 219 lock->win = XCreateWindow(dpy, lock->root, 0, 0, DisplayWidth(dpy, lock->screen), DisplayHeight(dpy, lock->screen),
213 0, DefaultDepth(dpy, lock->screen), CopyFromParent, 220 0, DefaultDepth(dpy, lock->screen), CopyFromParent,
214 DefaultVisual(dpy, lock->screen), CWOverrideRedirect | CWBackPixel, &wa); 221 DefaultVisual(dpy, lock->screen), CWOverrideRedirect | CWBackPixel, &wa);
215 XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), COLOR2, &color, &dummy); 222 XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), COLOR2, &color, &dummy);
216 lock->colors[1] = color.pixel; 223 lock->colors[1] = color.pixel;
217 XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), COLOR1, &color, &dummy); 224 XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), COLOR1, &color, &dummy);
@@ -220,36 +227,37 @@ lockscreen(Display *dpy, int screen) {
220 invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, &color, &color, 0, 0); 227 invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, &color, &color, 0, 0);
221 XDefineCursor(dpy, lock->win, invisible); 228 XDefineCursor(dpy, lock->win, invisible);
222 XMapRaised(dpy, lock->win); 229 XMapRaised(dpy, lock->win);
223 for(len = 1000; len; len--) { 230 for (len = 1000; len; len--) {
224 if(XGrabPointer(dpy, lock->root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, 231 if (XGrabPointer(dpy, lock->root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
225 GrabModeAsync, GrabModeAsync, None, invisible, CurrentTime) == GrabSuccess) 232 GrabModeAsync, GrabModeAsync, None, invisible, CurrentTime) == GrabSuccess)
226 break; 233 break;
227 usleep(1000); 234 usleep(1000);
228 } 235 }
229 if(running && (len > 0)) { 236 if (running && (len > 0)) {
230 for(len = 1000; len; len--) { 237 for (len = 1000; len; len--) {
231 if(XGrabKeyboard(dpy, lock->root, True, GrabModeAsync, GrabModeAsync, CurrentTime) 238 if (XGrabKeyboard(dpy, lock->root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess)
232 == GrabSuccess)
233 break; 239 break;
234 usleep(1000); 240 usleep(1000);
235 } 241 }
236 } 242 }
237 243
238 running &= (len > 0); 244 running &= (len > 0);
239 if(!running) { 245 if (!running) {
240 unlockscreen(dpy, lock); 246 unlockscreen(dpy, lock);
241 lock = NULL; 247 lock = NULL;
242 } 248 }
243 else 249 else {
244 XSelectInput(dpy, lock->root, SubstructureNotifyMask); 250 XSelectInput(dpy, lock->root, SubstructureNotifyMask);
251 }
245 252
246 return lock; 253 return lock;
247} 254}
248 255
249static void 256static void
250usage(void) { 257usage(void)
258{
251 fprintf(stderr, "usage: slock [-v]\n"); 259 fprintf(stderr, "usage: slock [-v]\n");
252 exit(EXIT_FAILURE); 260 exit(1);
253} 261}
254 262
255int 263int
@@ -260,38 +268,38 @@ main(int argc, char **argv) {
260 Display *dpy; 268 Display *dpy;
261 int screen; 269 int screen;
262 270
263 if((argc == 2) && !strcmp("-v", argv[1])) 271 if ((argc == 2) && !strcmp("-v", argv[1]))
264 die("slock-%s, © 2006-2014 slock engineers\n", VERSION); 272 die("slock-%s, © 2006-2015 slock engineers\n", VERSION);
265 else if(argc != 1) 273 else if (argc != 1)
266 usage(); 274 usage();
267 275
268#ifdef __linux__ 276#ifdef __linux__
269 dontkillme(); 277 dontkillme();
270#endif 278#endif
271 279
272 if(!getpwuid(getuid())) 280 if (!getpwuid(getuid()))
273 die("slock: no passwd entry for you\n"); 281 die("slock: no passwd entry for you\n");
274 282
275#ifndef HAVE_BSD_AUTH 283#ifndef HAVE_BSD_AUTH
276 pws = getpw(); 284 pws = getpw();
277#endif 285#endif
278 286
279 if(!(dpy = XOpenDisplay(0))) 287 if (!(dpy = XOpenDisplay(0)))
280 die("slock: cannot open display\n"); 288 die("slock: cannot open display\n");
281 /* Get the number of screens in display "dpy" and blank them all. */ 289 /* Get the number of screens in display "dpy" and blank them all. */
282 nscreens = ScreenCount(dpy); 290 nscreens = ScreenCount(dpy);
283 locks = malloc(sizeof(Lock *) * nscreens); 291 locks = malloc(sizeof(Lock *) * nscreens);
284 if(locks == NULL) 292 if (locks == NULL)
285 die("slock: malloc: %s\n", strerror(errno)); 293 die("slock: malloc: %s\n", strerror(errno));
286 int nlocks = 0; 294 int nlocks = 0;
287 for(screen = 0; screen < nscreens; screen++) { 295 for (screen = 0; screen < nscreens; screen++) {
288 if ( (locks[screen] = lockscreen(dpy, screen)) != NULL) 296 if ( (locks[screen] = lockscreen(dpy, screen)) != NULL)
289 nlocks++; 297 nlocks++;
290 } 298 }
291 XSync(dpy, False); 299 XSync(dpy, False);
292 300
293 /* Did we actually manage to lock something? */ 301 /* Did we actually manage to lock something? */
294 if (nlocks == 0) { // nothing to protect 302 if (nlocks == 0) { /* nothing to protect */
295 free(locks); 303 free(locks);
296 XCloseDisplay(dpy); 304 XCloseDisplay(dpy);
297 return 1; 305 return 1;
@@ -305,7 +313,7 @@ main(int argc, char **argv) {
305#endif 313#endif
306 314
307 /* Password ok, unlock everything and quit. */ 315 /* Password ok, unlock everything and quit. */
308 for(screen = 0; screen < nscreens; screen++) 316 for (screen = 0; screen < nscreens; screen++)
309 unlockscreen(dpy, locks[screen]); 317 unlockscreen(dpy, locks[screen]);
310 318
311 free(locks); 319 free(locks);