[hackers] [slock] error out early on crypt() fail || Markus Teich
commit a98fba8971ab4b8d8b1f18422b808a79434d8923 Author: Markus TeichAuthorDate: Fri Sep 23 19:08:39 2016 +0200 Commit: Markus Teich CommitDate: Fri Sep 23 19:08:39 2016 +0200 error out early on crypt() fail diff --git a/slock.c b/slock.c index 6dedc69..2d57e81 100644 --- a/slock.c +++ b/slock.c @@ -321,8 +321,9 @@ main(int argc, char **argv) { #endif hash = gethash(); - if (strlen(hash) < 2) - die("slock: failed to get user password hash.\n"); + errno = 0; + if (!crypt("", hash)) + die("slock: crypt: %s\n", strerror(errno)); if (!(dpy = XOpenDisplay(NULL))) die("slock: cannot open display\n");
[hackers] [slock] Stop using $USER for shadow entries || FRIGN
commit dc2e8e839e4d72f5fec36c9a0474e6062a7a8f51 Author: FRIGNAuthorDate: Sun Sep 11 23:17:53 2016 +0200 Commit: Markus Teich CommitDate: Fri Sep 23 18:54:56 2016 +0200 Stop using $USER for shadow entries This was extremely bad practice, effectively making the program behave different depending on which architecture you are running it on. OpenBSD offers getpwuid_shadow, but there is no getspuid for getspnam, so we resort to using the pw_name entry in the struct passwd we filled earlier. This prevents slock from crashing when $USER is empty (easy to do). If you want to run slock as a different user, don't use $ USER="tom" slock but doas or sudo which were designed for this purpose. diff --git a/slock.c b/slock.c index f799174..6dedc69 100644 --- a/slock.c +++ b/slock.c @@ -103,14 +103,14 @@ gethash(void) #if HAVE_SHADOW_H if (hash[0] == 'x' && hash[1] == '\0') { struct spwd *sp; - if (!(sp = getspnam(getenv("USER" + if (!(sp = getspnam(pw->pw_name))) die("slock: getspnam: cannot retrieve shadow entry (make sure to suid or sgid slock)\n"); hash = sp->sp_pwdp; } #else if (hash[0] == '*' && hash[1] == '\0') { #ifdef __OpenBSD__ - if (!(pw = getpwnam_shadow(getenv("USER" + if (!(pw = getpwuid_shadow(getuid( die("slock: getpwnam_shadow: cannot retrieve shadow entry (make sure to suid or sgid slock)\n"); hash = pw->pw_passwd; #else
[hackers] [slock] Remove cleanup and deglobalize and rework data structures || FRIGN
commit b00f444a4ea0d9ffa5cd7dcda71c97cdf05d322e Author: FRIGNAuthorDate: Sun Sep 11 23:08:19 2016 +0200 Commit: Markus Teich CommitDate: Fri Sep 23 18:39:01 2016 +0200 Remove cleanup and deglobalize and rework data structures The cleanup removal is a joint-venture with Markus. We assume the X server does the cleanup, so we don't need it. The idea is that the fds are closed at exit and thus already indicate to the X server that the client has quit. Analogously the same applies to freeing memory sections previously allocated for the X server. We love XL burgers and therefore removed XUngrabPointer XUngrabKeyboard XFreeColors XFreePixmap XDestroyWindow Lines of Code. For a project like slock there is no need to carry around global state. By moving the three structures to main() it is now clear which functions modify which state, greatly improving the readability of the code, especially given slock is a suid program. diff --git a/slock.c b/slock.c index 7127ebe..f423f8c 100644 --- a/slock.c +++ b/slock.c @@ -33,18 +33,18 @@ enum { #include "config.h" -typedef struct { +struct lock { int screen; Window root, win; Pixmap pmap; unsigned long colors[NUMCOLS]; -} Lock; +}; -static Lock **locks; -static int nscreens; -static Bool rr; -static int rrevbase; -static int rrerrbase; +struct xrandr { + int active; + int evbase; + int errbase; +}; static void die(const char *errstr, ...) @@ -123,7 +123,8 @@ getpw(void) } static void -readpw(Display *dpy, const char *pws) +readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + const char *pws) { char buf[32], passwd[256], *encrypted; int num, screen, running, failure; @@ -194,7 +195,7 @@ readpw(Display *dpy, const char *pws) } oldc = color; } - } else if (rr && ev.type == rrevbase + RRScreenChangeNotify) { + } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) { XRRScreenChangeNotifyEvent *rre = (XRRScreenChangeNotifyEvent*) for (screen = 0; screen < nscreens; screen++) { if (locks[screen]->win == rre->window) { @@ -207,44 +208,17 @@ readpw(Display *dpy, const char *pws) } } -static void -unlockscreen(Display *dpy, Lock *lock) -{ - if(dpy == NULL || lock == NULL) - return; - - XUngrabPointer(dpy, CurrentTime); - XUngrabKeyboard(dpy, CurrentTime); - XFreeColors(dpy, DefaultColormap(dpy, lock->screen), lock->colors, NUMCOLS, 0); - XFreePixmap(dpy, lock->pmap); - XDestroyWindow(dpy, lock->win); - - free(lock); -} - -static void -cleanup(Display *dpy) -{ - int s; - - for (s = 0; s < nscreens; ++s) - unlockscreen(dpy, locks[s]); - - free(locks); - XCloseDisplay(dpy); -} - -static Lock * -lockscreen(Display *dpy, int screen) +static struct lock * +lockscreen(Display *dpy, struct xrandr *rr, int screen) { char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; int i, ptgrab, kbgrab; - Lock *lock; + struct lock *lock; XColor color, dummy; XSetWindowAttributes wa; Cursor invisible; - if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(Lock + if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock return NULL; lock->screen = screen; @@ -281,7 +255,7 @@ lockscreen(Display *dpy, int screen) /* input is grabbed: we can lock the screen */ if (ptgrab == GrabSuccess && kbgrab == GrabSuccess) { XMapRaised(dpy, lock->win); - if (rr) + if (rr->active) XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask); XSelectInput(dpy, lock->root, SubstructureNotifyMask); @@ -312,13 +286,15 @@ usage(void) int main(int argc, char **argv) { + struct xrandr rr; + struct lock **locks; struct passwd *pwd; struct group *grp; uid_t duid; gid_t dgid; const char *pws; Display *dpy; - int s, nlocks; + int s, nlocks, nscreens; ARGBEGIN { case 'v': @@ -360,16 +336,14 @@ main(int argc, char **argv) { die("slock: setuid: %s\n", strerror(errno)); /* check for Xrandr support */ - rr = XRRQueryExtension(dpy, , ); + rr.active = XRRQueryExtension(dpy, , ); /* get number of screens in display "dpy" and blank them */ nscreens = ScreenCount(dpy); - if (!(locks = calloc(nscreens, sizeof(Lock * { - XCloseDisplay(dpy); + if
[hackers] [slock] Rename getpw() and pws to gethash() and hash || FRIGN
commit 9a617db716641da8489e2062e04098220954bffe Author: FRIGNAuthorDate: Sun Sep 11 23:10:57 2016 +0200 Commit: Markus Teich CommitDate: Fri Sep 23 18:51:40 2016 +0200 Rename getpw() and pws to gethash() and hash diff --git a/slock.c b/slock.c index f423f8c..f799174 100644 --- a/slock.c +++ b/slock.c @@ -85,9 +85,9 @@ dontkillme(void) #endif static const char * -getpw(void) +gethash(void) { - const char *rval; + const char *hash; struct passwd *pw; /* Check if the current user has a password entry */ @@ -98,35 +98,35 @@ getpw(void) else die("slock: cannot retrieve password entry\n"); } - rval = pw->pw_passwd; + hash = pw->pw_passwd; #if HAVE_SHADOW_H - if (rval[0] == 'x' && rval[1] == '\0') { + if (hash[0] == 'x' && hash[1] == '\0') { struct spwd *sp; if (!(sp = getspnam(getenv("USER" die("slock: getspnam: cannot retrieve shadow entry (make sure to suid or sgid slock)\n"); - rval = sp->sp_pwdp; + hash = sp->sp_pwdp; } #else - if (rval[0] == '*' && rval[1] == '\0') { + if (hash[0] == '*' && hash[1] == '\0') { #ifdef __OpenBSD__ if (!(pw = getpwnam_shadow(getenv("USER" die("slock: getpwnam_shadow: cannot retrieve shadow entry (make sure to suid or sgid slock)\n"); - rval = pw->pw_passwd; + hash = pw->pw_passwd; #else die("slock: getpwuid: cannot retrieve shadow entry (make sure to suid or sgid slock)\n"); #endif /* __OpenBSD__ */ } #endif /* HAVE_SHADOW_H */ - return rval; + return hash; } static void readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, - const char *pws) + const char *hash) { - char buf[32], passwd[256], *encrypted; + char buf[32], passwd[256], *inputhash; int num, screen, running, failure; unsigned int len, color; KeySym ksym; @@ -161,10 +161,10 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, case XK_Return: passwd[len] = 0; errno = 0; - if (!(encrypted = crypt(passwd, pws))) + if (!(inputhash = crypt(passwd, hash))) fprintf(stderr, "slock: crypt: %s\n", strerror(errno)); else - running = !!strcmp(encrypted, pws); + running = !!strcmp(inputhash, hash); if (running) { XBell(dpy, 100); failure = True; @@ -292,7 +292,7 @@ main(int argc, char **argv) { struct group *grp; uid_t duid; gid_t dgid; - const char *pws; + const char *hash; Display *dpy; int s, nlocks, nscreens; @@ -320,8 +320,8 @@ main(int argc, char **argv) { dontkillme(); #endif - pws = getpw(); - if (strlen(pws) < 2) + hash = gethash(); + if (strlen(hash) < 2) die("slock: failed to get user password hash.\n"); if (!(dpy = XOpenDisplay(NULL))) @@ -370,7 +370,7 @@ main(int argc, char **argv) { } /* everything is now blank. Wait for the correct password */ - readpw(dpy, , locks, nscreens, pws); + readpw(dpy, , locks, nscreens, hash); return 0; }
Re: [hackers] [surf/surf-webkit2] Add support for loading Webkit extensions || Quentin Rameau
On Thu, Sep 22, 2016 at 10:22:14AM +0200, g...@suckless.org wrote: > commit da5290a41aac4eabef83f6b88039f44d28b0ea00 > Author: Quentin Rameau> AuthorDate: Mon Nov 23 22:12:00 2015 +0100 > Commit: Quentin Rameau > CommitDate: Thu Sep 22 10:21:31 2016 +0200 > > Add support for loading Webkit extensions > I like it, I like it alawt[0]. For the interested I'm working on an adblocker (with emotional support from Quentin). It is a work-in-progress but available at: https://git.codemadness.org/surf-adblock/files.html For now it can only read adblock/ublock rules in a basic manner and block basic content types. Have fun and happy hacking! [0] - https://www.youtube.com/watch?v=28GLa9T2CtI > diff --git a/config.mk b/config.mk > index e71316c..c0a9959 100644 > --- a/config.mk > +++ b/config.mk > @@ -6,6 +6,7 @@ VERSION = 0.6 > # paths > PREFIX = /usr/local > MANPREFIX = ${PREFIX}/share/man > +LIBPREFIX = ${PREFIX}/lib/surf > > X11INC = /usr/X11R6/include > X11LIB = /usr/X11R6/lib > @@ -18,7 +19,7 @@ INCS = -I. -I/usr/include -I${X11INC} ${GTKINC} > LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${GTKLIB} -lgthread-2.0 > > # flags > -CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE > +CPPFLAGS = -DVERSION=\"${VERSION}\" -DWEBEXTDIR=\"${LIBPREFIX}\" > -D_DEFAULT_SOURCE > CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} > LDFLAGS = -s ${LIBS} > > diff --git a/surf.c b/surf.c > index 29b9ede..fb3ef81 100644 > --- a/surf.c > +++ b/surf.c > @@ -175,6 +175,7 @@ static void cleanup(void); > > /* GTK/WebKit */ > static WebKitWebView *newview(Client *c, WebKitWebView *rv); > +static void initwebextensions(WebKitWebContext *wc, Client *c); > static GtkWidget *createview(WebKitWebView *v, WebKitNavigationAction *a, > Client *c); > static gboolean buttonreleased(GtkWidget *w, GdkEvent *e, Client *c); > @@ -980,6 +981,8 @@ newview(Client *c, WebKitWebView *rv) > > g_signal_connect(G_OBJECT(context), "download-started", >G_CALLBACK(downloadstarted), c); > + g_signal_connect(G_OBJECT(context), "initialize-web-extensions", > + G_CALLBACK(initwebextensions), c); > > v = g_object_new(WEBKIT_TYPE_WEB_VIEW, > "settings", settings, > @@ -1012,6 +1015,12 @@ newview(Client *c, WebKitWebView *rv) > return v; > } > > +void > +initwebextensions(WebKitWebContext *wc, Client *c) > +{ > + webkit_web_context_set_web_extensions_directory(wc, WEBEXTDIR); > +} > + > GtkWidget * > createview(WebKitWebView *v, WebKitNavigationAction *a, Client *c) > { > -- Kind regards, Hiltjo
Re: [hackers] [sinit] [PATCH] Use switch for fork()
Applied the patch, thanks! (BTW commit message is too bloated).
[hackers] [sinit] Use switch for fork() || FRIGN
commit 731f65fc82afcd474f4c682f9f0069e5c80c86dd Author: FRIGNAuthorDate: Fri Sep 23 09:37:59 2016 +0200 Commit: sin CommitDate: Fri Sep 23 09:33:22 2016 +0100 Use switch for fork() This saves us one local variable and 2 lines of code, while improving readability by using the switch-style we are used to from other suckless projects. We are allowed to check against -1, as POSIX clearly mandates for the RETURN VALUE: "Upon successful completion, fork() shall return 0 to the child process and shall return the process ID of the child process to the parent process. Both processes shall continue to execute from the fork() function. Otherwise, -1 shall be returned to the parent process, no child process shall be created, and errno shall be set to indicate the error." [http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html] This way, checking against < 0 was overdoing it and it's sufficient to compare against -1, justifying the switch statement here. diff --git a/sinit.c b/sinit.c index e338f35..93f9925 100644 --- a/sinit.c +++ b/sinit.c @@ -74,16 +74,14 @@ sigreboot(void) static void spawn(char *const argv[]) { - pid_t pid; - - pid = fork(); - if (pid < 0) { - perror("fork"); - } else if (pid == 0) { + switch (fork()) { + case 0: sigprocmask(SIG_UNBLOCK, , NULL); setsid(); execvp(argv[0], argv); perror("execvp"); _exit(1); + case -1: + perror("fork"); } }
Re: [hackers] [sinit] [PATCH] Use switch for fork()
On Fri, Sep 23, 2016 at 9:48 AM, FRIGNwrote: > To be precise, I think this can be considered the first patch of this > year's slcon3 hacking sessions. ;) Haha, so early... I will be arriving around 21h tonight. I assume that there will be more time for coding on Sunday as well! Cheers, Silvan
[hackers] [sinit] [PATCH] Use switch for fork()
Hello fellow hackers, I spotted this small detail this morning and applied this change. It is always a good thing in my opinion to be able to carve off an unnecessary local variable. To be precise, I think this can be considered the first patch of this year's slcon3 hacking sessions. ;) With best regards FRIGN -- FRIGN>From 6365fab78c11e8269447cf0cfcbb1aeac618488b Mon Sep 17 00:00:00 2001 From: FRIGN Date: Fri, 23 Sep 2016 09:37:59 +0200 Subject: [PATCH] Use switch for fork() This saves us one local variable and 2 lines of code, while improving readability by using the switch-style we are used to from other suckless projects. We are allowed to check against -1, as POSIX clearly mandates for the RETURN VALUE: "Upon successful completion, fork() shall return 0 to the child process and shall return the process ID of the child process to the parent process. Both processes shall continue to execute from the fork() function. Otherwise, -1 shall be returned to the parent process, no child process shall be created, and errno shall be set to indicate the error." [http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html] This way, checking against < 0 was overdoing it and it's sufficient to compare against -1, justifying the switch statement here. --- sinit.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sinit.c b/sinit.c index e338f35..93f9925 100644 --- a/sinit.c +++ b/sinit.c @@ -74,16 +74,14 @@ sigreboot(void) static void spawn(char *const argv[]) { - pid_t pid; - - pid = fork(); - if (pid < 0) { - perror("fork"); - } else if (pid == 0) { + switch (fork()) { + case 0: sigprocmask(SIG_UNBLOCK, , NULL); setsid(); execvp(argv[0], argv); perror("execvp"); _exit(1); + case -1: + perror("fork"); } } -- 2.7.3