Created
October 16, 2015 01:49
-
-
Save ephemient/daafa8b001a46004f649 to your computer and use it in GitHub Desktop.
libcmdsdaskpass.so
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#/* \ | |
make -C "$(dirname "$0")" -f "$0" "$@"; exit $? | |
libcmdsdaskpass.so: LDFLAGS += -shared | |
libcmdsdaskpass.so: LDLIBS += -ldl | |
libcmdsdaskpass.so: cmdsdaskpass.o | |
$(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o $@ | |
cmdsdaskpass.o: CFLAGS += -fPIC | |
cmdsdaskpass.o: cmdsdaskpass.c | |
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $^ | |
help: | |
$(info ) | |
$(info LD_PRELOAD to replace $$(systemd-ask-password $$*) with the result of invocation) | |
$(info in ARGV without being visible in /proc/$$/cmdline, building on code taken from) | |
$(info http://serverfault.com/a/592941) | |
$(info http://xrefactor.com/blog/polyglot-in-c-makefile-and-shell-script) | |
$(info ) | |
.PHONY: help | |
#*/ | |
#define _GNU_SOURCE | |
#include <dlfcn.h> | |
#include <errno.h> | |
#include <fcntl.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <sys/wait.h> | |
#include <sysexits.h> | |
#include <unistd.h> | |
static int (*real_main)(int, char **, char **); | |
static const char replace_arg_begin[] = "$(systemd-ask-password"; | |
static const char replace_arg_end[] = ")"; | |
static const char sd_askpass_cmd[] = "/usr/bin/systemd-ask-password"; | |
static const char whitespace[] = " \t\n"; | |
static int preload_main(int argc, char **argv, char **envp) { | |
int i, j, fds[2]; | |
for (i = 1; i < argc; i++) { | |
int begin = strlen(replace_arg_begin); | |
int end = strlen(argv[i]) - strlen(replace_arg_end); | |
if (begin < end && | |
memcmp(argv[i], replace_arg_begin, strlen(replace_arg_begin)) == 0 && | |
memcmp(argv[i] + end, replace_arg_end, strlen(replace_arg_end)) == 0) { | |
pid_t child; | |
char *s, *args = malloc(end - begin + 1); | |
const char **arga = calloc((end - begin + 1) / 2 + 2, sizeof(char *)); | |
memcpy(args, argv[i] + begin, end - begin); | |
args[end - begin] = '\0'; | |
arga[0] = sd_askpass_cmd; | |
for (j = 1, s = args + strspn(args, whitespace); s[0]; s += strspn(s, whitespace)) { | |
arga[j++] = s; | |
if (s[0] == '-' && (s[1] != '-' || s[2] != '\0' && !strchr(whitespace, s[2]))) { | |
s += strcspn(s, whitespace); | |
if (s[0]) { | |
*s++ = '\0'; | |
} | |
} else if (s[0] == '-' && s[1] == '-') { | |
(s += 2)[0] = '\0'; | |
if (&s[1] < &args[end - begin]) { | |
s += 1 + strspn(&s[1], whitespace); | |
} | |
if (s < &args[end - begin]) { | |
arga[j++] = s; | |
s = &args[end - begin]; | |
} | |
} else { | |
break; | |
} | |
} | |
if (pipe2(fds, O_CLOEXEC) < 0) { | |
perror("pipe2"); | |
exit(EX_OSERR); | |
} | |
if ((child = fork()) < 0) { | |
perror("fork"); | |
exit(EX_OSERR); | |
} else if (child == 0) { | |
if (fds[0] != 1) { | |
close(fds[0]); | |
} | |
if (fds[1] != 1) { | |
dup2(fds[1], 1); | |
close(fds[1]); | |
} | |
execvp(arga[0], (char **)arga); | |
perror("execv"); | |
_exit(EX_UNAVAILABLE); | |
} else { | |
FILE *p; | |
size_t n = 0; | |
free(arga); | |
free(args); | |
close(fds[1]); | |
if (!(p = fdopen(fds[0], "r"))) { | |
perror("child"); | |
exit(EX_NOINPUT); | |
} | |
args = NULL; | |
j = getline(&args, &n, p); | |
if (j < 0) { | |
perror("getline"); | |
exit(EX_NOINPUT); | |
} | |
fclose(p); | |
close(fds[0]); | |
if (args[j - 1] == '\n') { | |
args[j - 1] = '\0'; | |
} | |
argv[i] = args; | |
} | |
} | |
} | |
return real_main(argc, argv, envp); | |
} | |
int __libc_start_main( | |
int (*main)(int, char **, char **), | |
int argc, char **ubp_av, | |
void (*init)(void), | |
void (*fini)(void), | |
void (*rtld_fini)(void), | |
void *stack_end) { | |
int (*next)( | |
int (*)(int, char **, char **), | |
int, char **, | |
void (*)(void), | |
void (*)(void), | |
void (*)(void), | |
void *) = | |
dlsym(RTLD_NEXT, __func__); | |
real_main = main; | |
return next(preload_main, argc, ubp_av, init, fini, rtld_fini, stack_end); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment